* [PATCH 10/52] [microblaze] Generic dts file for platforms
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 11/52] [microblaze] kernel modules support monstr
` (50 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/platform/generic/system.dts | 137 +++++++++++++++++++++++++++
1 files changed, 137 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/platform/generic/system.dts
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
new file mode 100644
index 0000000..91eac31
--- /dev/null
+++ b/arch/microblaze/platform/generic/system.dts
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 9.2 EDK_Jm.16
+ * Generate by U-BOOT v4.00.b
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ibm,opb";
+ model = "testing";
+ DDR_SDRAM_32Mx16: memory@44000000 {
+ device_type = "memory";
+ reg = < 44000000 2000000 >;
+ } ;
+ chosen {
+ bootargs = "root=mtdblock0";
+ } ;
+ cpus {
+ #address-cells = <1>;
+ #cpus = <1>;
+ #size-cells = <0>;
+ microblaze,5.00.c@0 {
+ clock-frequency = <3f940ab>;
+ d-cache-baseaddr = <44000000>;
+ d-cache-highaddr = <47ffffff>;
+ d-cache-line-size = <10>;
+ d-cache-size = <2000>;
+ device_type = "cpu";
+ i-cache-baseaddr = <44000000>;
+ i-cache-highaddr = <47ffffff>;
+ i-cache-line-size = <10>;
+ i-cache-size = <2000>;
+ reg = <0>;
+ timebase-frequency = <3f940ab>;
+ xlnx,addr-tag-bits = <d>;
+ xlnx,allow-dcache-wr = <1>;
+ xlnx,allow-icache-wr = <1>;
+ xlnx,cache-byte-size = <2000>;
+ xlnx,d-lmb = <1>;
+ xlnx,d-opb = <1>;
+ xlnx,data-size = <20>;
+ xlnx,dcache-addr-tag = <d>;
+ xlnx,dcache-byte-size = <2000>;
+ xlnx,dcache-line-len = <4>;
+ xlnx,dcache-use-fsl = <1>;
+ xlnx,debug-enabled = <1>;
+ xlnx,div-zero-exception = <0>;
+ xlnx,dopb-bus-exception = <0>;
+ xlnx,dynamic-bus-sizing = <1>;
+ xlnx,edge-is-positive = <1>;
+ xlnx,fpu-exception = <0>;
+ xlnx,fsl-data-size = <20>;
+ xlnx,fsl-links = <1>;
+ xlnx,i-lmb = <1>;
+ xlnx,i-opb = <1>;
+ xlnx,icache-line-len = <4>;
+ xlnx,icache-use-fsl = <1>;
+ xlnx,ill-opcode-exception = <0>;
+ xlnx,instance = "microblaze_0";
+ xlnx,interrupt-is-edge = <0>;
+ xlnx,iopb-bus-exception = <0>;
+ xlnx,number-of-pc-brk = <2>;
+ xlnx,number-of-rd-addr-brk = <0>;
+ xlnx,number-of-wr-addr-brk = <0>;
+ xlnx,opcode-0x0-illegal = <0>;
+ xlnx,pvr = <2>;
+ xlnx,pvr-user1 = <0>;
+ xlnx,pvr-user2 = <0>;
+ xlnx,reset-msr = <0>;
+ xlnx,sco = <0>;
+ xlnx,unaligned-exceptions = <0>;
+ xlnx,use-barrel = <1>;
+ xlnx,use-dcache = <1>;
+ xlnx,use-div = <1>;
+ xlnx,use-fpu = <0>;
+ xlnx,use-hw-mul = <1>;
+ xlnx,use-icache = <1>;
+ xlnx,use-msr-instr = <1>;
+ xlnx,use-pcmp-instr = <1>;
+ } ;
+ } ;
+ opb_v20 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,opb-v20-1.10.c", "xlnx,opb-v20";
+ RS232_DTE: serial@40600000 {
+ compatible = "xlnx,opb-uartlite-1.00.b", "xlnx,opb-uartlite", "xilinx,uartlite";
+ interrupt-parent = <&opb_intc_0>;
+ interrupts = < 2 0 >;
+ reg = < 40600000 10000 >;
+ xlnx,baudrate = <1c200>;
+ xlnx,clk-freq = <3f940ab>;
+ xlnx,data-bits = <8>;
+ xlnx,odd-parity = <0>;
+ xlnx,use-parity = <0>;
+ } ;
+ opb_intc_0: interrupt-controller@41200000 {
+ #interrupt-cells = <2>;
+ compatible = "xlnx,opb-intc-1.00.c", "xlnx,opb-intc";
+ interrupt-controller ;
+ reg = < 41200000 10000 >;
+ xlnx,num-intr-inputs = <5>;
+ } ;
+ opb_timer_0: opb-timer@41c00000 {
+ compatible = "xlnx,opb-timer-1.00.b", "xlnx,opb-timer";
+ interrupt-parent = <&opb_intc_0>;
+ interrupts = < 0 0 >;
+ reg = < 41c00000 10000 >;
+ xlnx,count-width = <20>;
+ xlnx,gen0-assert = <1>;
+ xlnx,gen1-assert = <1>;
+ xlnx,one-timer-only = <1>;
+ xlnx,trig0-assert = <1>;
+ xlnx,trig1-assert = <1>;
+ } ;
+ } ;
+} ;
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 11/52] [microblaze] kernel modules support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
2008-01-24 15:02 ` [PATCH 10/52] [microblaze] Generic dts file for platforms monstr
@ 2008-01-24 15:02 ` monstr
2008-01-26 16:27 ` Jan Engelhardt
2008-01-24 15:02 ` [PATCH 12/52] [microblaze] lmb support monstr
` (49 subsequent siblings)
51 siblings, 1 reply; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/microblaze_ksyms.c | 129 +++++++++++++++++++++++++
arch/microblaze/kernel/module.c | 149 +++++++++++++++++++++++++++++
include/asm-microblaze/module.h | 41 ++++++++
3 files changed, 319 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/microblaze_ksyms.c
create mode 100644 arch/microblaze/kernel/module.c
create mode 100644 include/asm-microblaze/module.h
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
new file mode 100644
index 0000000..7ce8b36
--- /dev/null
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -0,0 +1,129 @@
+/*
+ * linux/arch/microblaze/kernel/microblazeksyms.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/cryptohash.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/syscalls.h>
+
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+/* module handling */
+EXPORT_SYMBOL(PAGE_OFFSET);
+
+/*
+ * floating point math emulator support.
+ * These symbols will never change their calling convention...
+ */
+/* EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
+EXPORT_SYMBOL_ALIAS(fp_printk,printk);
+EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
+
+EXPORT_SYMBOL(__backtrace); */
+
+ /* platform dependent support */
+/* EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__const_udelay); */
+
+ /* networking */
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+EXPORT_SYMBOL(ip_compute_csum);
+
+ /* io */
+/*#ifndef __raw_readsb
+EXPORT_SYMBOL(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL(__raw_writesl);
+#endif*/
+
+ /* string / mem functions */
+/*EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);*/
+
+#ifdef __HAVE_ARCH_MEMSET
+EXPORT_SYMBOL(memset);
+#endif
+
+#ifdef __HAVE_ARCH_MEMCPY
+EXPORT_SYMBOL(memcpy);
+#endif
+
+#ifdef __HAVE_ARCH_MEMMOVE
+EXPORT_SYMBOL(memmove);
+#endif
+
+/* EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(__memzero); */
+
+ /* user mem (segment) */
+/* EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(__strncpy_from_user); */
+
+ /* crypto hash */
+/* EXPORT_SYMBOL(sha_transform); */
+
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+EXPORT_SYMBOL(__ashldi3);
+extern void __ashrdi3(void);
+EXPORT_SYMBOL(__ashrdi3);
+extern void __divsi3(void);
+EXPORT_SYMBOL(__divsi3);
+extern void __lshrdi3(void);
+EXPORT_SYMBOL(__lshrdi3);
+extern void __modsi3(void);
+EXPORT_SYMBOL(__modsi3);
+extern void __mulsi3(void);
+EXPORT_SYMBOL(__mulsi3);
+extern void __muldi3(void);
+EXPORT_SYMBOL(__muldi3);
+extern void __ucmpdi2(void);
+EXPORT_SYMBOL(__ucmpdi2);
+extern void __udivsi3(void);
+EXPORT_SYMBOL(__udivsi3);
+extern void __umodsi3(void);
+EXPORT_SYMBOL(__umodsi3);
+/*extern void fpundefinstr(void);
+extern void fp_enter(void);*/
+
+ /* bitops */
+/* EXPORT_SYMBOL(_set_bit_le);
+EXPORT_SYMBOL(_test_and_set_bit_le);
+EXPORT_SYMBOL(_clear_bit_le);
+EXPORT_SYMBOL(_test_and_clear_bit_le);
+EXPORT_SYMBOL(_change_bit_le);
+EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_find_first_zero_bit_le);
+EXPORT_SYMBOL(_find_next_zero_bit_le);
+EXPORT_SYMBOL(_find_first_bit_le);
+EXPORT_SYMBOL(_find_next_bit_le); */
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
new file mode 100644
index 0000000..d2befac
--- /dev/null
+++ b/arch/microblaze/kernel/module.c
@@ -0,0 +1,149 @@
+/*
+ * linux/arch/microblaze/kernel/module.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/kernel.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+
+#include <asm/pgtable.h>
+
+#if 0
+#define DBPRINTK(...) printk(__VA_ARGS__)
+#else
+#define DBPRINTK(...)
+#endif
+
+void *module_alloc(unsigned long size)
+{
+ void *ret;
+ ret = (size == 0) ? NULL : vmalloc(size);
+ DBPRINTK("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
+ return ret;
+}
+
+void module_free(struct module *module, void *region)
+{
+ DBPRINTK("module_free(%s,%08lx)\n", module->name, region);
+ vfree(region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+ Elf_Shdr *sechdrs,
+ char *secstrings,
+ struct module *mod)
+{
+ return 0;
+}
+
+int
+apply_relocate(Elf32_Shdr * sechdrs, const char *strtab, unsigned int symindex,
+ unsigned int relsec, struct module *module)
+{
+
+ printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+ module->name);
+ return -ENOEXEC;
+
+}
+
+int
+apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *module)
+{
+
+ unsigned int i;
+ Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ unsigned long int *location;
+ unsigned long int locoffs;
+ unsigned long int value;
+ unsigned long int old_value;
+
+ DBPRINTK("Applying add relocation section %u to %u\n",
+ relsec, sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
+ rela[i].r_offset;
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
+ ELF32_R_SYM(rela[i].r_info);
+ value = sym->st_value + rela[i].r_addend;
+
+ switch (ELF32_R_TYPE(rela[i].r_info)) {
+
+ /*
+ * Be careful! mb-gcc / mb-ld splits the relocs between the
+ * text and the reloc table. In general this means we must
+ * read the current contents of (*location), add any offset
+ * then store the result back in
+ */
+
+ case R_MICROBLAZE_32:
+ old_value = *location;
+ *location = value + old_value;
+ DBPRINTK("R_MICROBLAZE_32 (%08lx->%08lx)\n",
+ old_value, value);
+ break;
+
+ case R_MICROBLAZE_64:
+ old_value = ((location[0] & 0x0000FFFF) << 16) |
+ ((location[1] & 0x0000FFFF));
+ value += old_value;
+ location[0] = (location[0] & 0xFFFF0000) |
+ (value >> 16);
+ location[1] = (location[1] & 0xFFFF0000) |
+ (value & 0xFFFF);
+ DBPRINTK("R_MICROBLAZE_64 (%08lx->%08lx)\n",
+ old_value, value);
+ break;
+
+ case R_MICROBLAZE_64_PCREL:
+ locoffs = (location[0] & 0xFFFF) << 16 |
+ (location[1] & 0xFFFF);
+ value -= (unsigned long int)(location) + 4 +
+ locoffs;
+ location[0] = (location[0] & 0xFFFF0000) |
+ (value >> 16);
+ location[1] = (location[1] & 0xFFFF0000) |
+ (value & 0xFFFF);
+ DBPRINTK("R_MICROBLAZE_64_PCREL (%08lx)\n",
+ value);
+ break;
+
+ case R_MICROBLAZE_NONE:
+ DBPRINTK("R_MICROBLAZE_NONE\n");
+ break;
+
+ default:
+ printk(KERN_ERR "module %s: "
+ "Unknown relocation: %u\n",
+ module->name,
+ ELF32_R_TYPE(rela->r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int
+module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr *sechdrs,
+ struct module *module)
+{
+ return 0;
+}
+
+void
+module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/include/asm-microblaze/module.h b/include/asm-microblaze/module.h
new file mode 100644
index 0000000..97416e0
--- /dev/null
+++ b/include/asm-microblaze/module.h
@@ -0,0 +1,41 @@
+/*
+ * include/asm-microblaze/module.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+#define EM_XILINX_MICROBLAZE 0xbaab
+
+/* Microblaze Relocations */
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+/* Keep this the last entry. */
+#define R_MICROBLAZE_NUM 11
+
+struct mod_arch_specific {
+ int foo;
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+typedef struct { volatile int counter; } module_t;
+
+#endif /* _ASM_MODULE_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 11/52] [microblaze] kernel modules support
2008-01-24 15:02 ` [PATCH 11/52] [microblaze] kernel modules support monstr
@ 2008-01-26 16:27 ` Jan Engelhardt
0 siblings, 0 replies; 67+ messages in thread
From: Jan Engelhardt @ 2008-01-26 16:27 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Jan 24 2008 16:02, monstr@monstr.eu wrote:
>+
>+/* module handling */
>+EXPORT_SYMBOL(PAGE_OFFSET);
This looks really ugly. PAGE_OFFSET is usually a macro.
I looked in patch 29/52 where PAGE_OFFSET is defined (unsigned int
PAGE_OFFSET), which got me wondered: PAGE_OFFSET can be a runtime
variable when it is a constant on most other arches?
That being said, I'd use
#define PAGE_OFFSET __page_offset
in some header file and in the .c file:
unsigned int __page_offset;
EXPORT_SYMBOL(__page_offset);
that is how arch-frv and -uml seem to do it.
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 12/52] [microblaze] lmb support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
2008-01-24 15:02 ` [PATCH 10/52] [microblaze] Generic dts file for platforms monstr
2008-01-24 15:02 ` [PATCH 11/52] [microblaze] kernel modules support monstr
@ 2008-01-24 15:02 ` monstr
2008-01-27 12:51 ` Jan Engelhardt
2008-01-24 15:02 ` [PATCH 13/52] [microblaze] PVR support, cpuinfo support monstr
` (48 subsequent siblings)
51 siblings, 1 reply; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/mm/lmb.c | 342 ++++++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/lmb.h | 84 ++++++++++
2 files changed, 426 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/mm/lmb.c
create mode 100644 include/asm-microblaze/lmb.h
diff --git a/arch/microblaze/mm/lmb.c b/arch/microblaze/mm/lmb.c
new file mode 100644
index 0000000..993ea49
--- /dev/null
+++ b/arch/microblaze/mm/lmb.c
@@ -0,0 +1,342 @@
+/*
+ * Procedures for maintaining information about logical memory blocks.
+ *
+ * Peter Bergner, IBM Corp. June 2001.
+ * Copyright (C) 2001 Peter Bergner.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#ifdef CONFIG_PPC32
+#include "mmu_decl.h" /* for __max_low_memory */
+#endif
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#define LMB_ALLOC_ANYWHERE 0
+
+struct lmb lmb;
+
+void lmb_dump_all(void)
+{
+#ifdef DEBUG
+ unsigned int i;
+
+ DBG("lmb_dump_all:\n");
+ DBG(" memory.cnt = 0x%lx\n", lmb.memory.cnt);
+ DBG(" memory.size = 0x%lx\n", lmb.memory.size);
+ for (i = 0; i < lmb.memory.cnt ; i++) {
+ DBG(" memory.region[0x%x].base = 0x%lx\n",
+ i, lmb.memory.region[i].base);
+ DBG(" .size = 0x%lx\n",
+ lmb.memory.region[i].size);
+ }
+
+ DBG("\n reserved.cnt = 0x%lx\n", lmb.reserved.cnt);
+ DBG(" reserved.size = 0x%lx\n", lmb.reserved.size);
+ for (i = 0; i < lmb.reserved.cnt ; i++) {
+ DBG(" reserved.region[0x%x].base = 0x%lx\n",
+ i, lmb.reserved.region[i].base);
+ DBG(" .size = 0x%lx\n",
+ lmb.reserved.region[i].size);
+ }
+#endif /* DEBUG */
+}
+
+static unsigned long __init lmb_addrs_overlap(unsigned long base1,
+ unsigned long size1, unsigned long base2, unsigned long size2)
+{
+ return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+}
+
+static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+ unsigned long base2, unsigned long size2)
+{
+ if (base2 == base1 + size1)
+ return 1;
+ else if (base1 == base2 + size2)
+ return -1;
+
+ return 0;
+}
+
+static long __init lmb_regions_adjacent(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
+{
+ unsigned long base1 = rgn->region[r1].base;
+ unsigned long size1 = rgn->region[r1].size;
+ unsigned long base2 = rgn->region[r2].base;
+ unsigned long size2 = rgn->region[r2].size;
+
+ return lmb_addrs_adjacent(base1, size1, base2, size2);
+}
+
+static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r)
+{
+ unsigned long i;
+
+ for (i = r; i < rgn->cnt - 1; i++) {
+ rgn->region[i].base = rgn->region[i + 1].base;
+ rgn->region[i].size = rgn->region[i + 1].size;
+ }
+ rgn->cnt--;
+}
+
+/* Assumption: base addr of region 1 < base addr of region 2 */
+static void __init lmb_coalesce_regions(struct lmb_region *rgn,
+ unsigned long r1, unsigned long r2)
+{
+ rgn->region[r1].size += rgn->region[r2].size;
+ lmb_remove_region(rgn, r2);
+}
+
+/* This routine called with relocation disabled. */
+void __init lmb_init(void)
+{
+ /* Create a dummy zero size LMB which will get coalesced away later.
+ * This simplifies the lmb_add() code below...
+ */
+ lmb.memory.region[0].base = 0;
+ lmb.memory.region[0].size = 0;
+ lmb.memory.cnt = 1;
+
+ /* Ditto. */
+ lmb.reserved.region[0].base = 0;
+ lmb.reserved.region[0].size = 0;
+ lmb.reserved.cnt = 1;
+}
+
+/* This routine may be called with relocation disabled. */
+void __init lmb_analyze(void)
+{
+ int i;
+
+ lmb.memory.size = 0;
+
+ for (i = 0; i < lmb.memory.cnt; i++)
+ lmb.memory.size += lmb.memory.region[i].size;
+}
+
+/* This routine called with relocation disabled. */
+static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
+{
+ unsigned long i, coalesced = 0;
+ long adjacent;
+
+ /* First try and coalesce this LMB with another. */
+ for (i = 0; i < rgn->cnt; i++) {
+ unsigned long rgnbase = rgn->region[i].base;
+ unsigned long rgnsize = rgn->region[i].size;
+
+ if ((rgnbase == base) && (rgnsize == size))
+ /* Already have this region, so we're done */
+ return 0;
+
+ adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize);
+ if (adjacent > 0) {
+ rgn->region[i].base -= size;
+ rgn->region[i].size += size;
+ coalesced++;
+ break;
+ } else if (adjacent < 0) {
+ rgn->region[i].size += size;
+ coalesced++;
+ break;
+ }
+ }
+
+ if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i + 1)) {
+ lmb_coalesce_regions(rgn, i, i+1);
+ coalesced++;
+ }
+
+ if (coalesced)
+ return coalesced;
+ if (rgn->cnt >= MAX_LMB_REGIONS)
+ return -1;
+
+ /* Couldn't coalesce the LMB, so add it to the sorted table. */
+ for (i = rgn->cnt-1; i >= 0; i--) {
+ if (base < rgn->region[i].base) {
+ rgn->region[i+1].base = rgn->region[i].base;
+ rgn->region[i+1].size = rgn->region[i].size;
+ } else {
+ rgn->region[i+1].base = base;
+ rgn->region[i+1].size = size;
+ break;
+ }
+ }
+ rgn->cnt++;
+
+ return 0;
+}
+
+/* This routine may be called with relocation disabled. */
+long __init lmb_add(unsigned long base, unsigned long size)
+{
+ struct lmb_region *_rgn = &(lmb.memory);
+
+ /* On pSeries LPAR systems, the first LMB is our RMO region. */
+ if (base == 0)
+ lmb.rmo_size = size;
+
+ return lmb_add_region(_rgn, base, size);
+
+}
+
+long __init lmb_reserve(unsigned long base, unsigned long size)
+{
+ struct lmb_region *_rgn = &(lmb.reserved);
+
+ BUG_ON(0 == size);
+
+ return lmb_add_region(_rgn, base, size);
+}
+
+long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
+ unsigned long size)
+{
+ unsigned long i;
+
+ for (i = 0; i < rgn->cnt; i++) {
+ unsigned long rgnbase = rgn->region[i].base;
+ unsigned long rgnsize = rgn->region[i].size;
+ if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
+ break;
+ }
+
+ return (i < rgn->cnt) ? i : -1;
+}
+
+unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
+{
+ return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
+}
+
+unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
+ unsigned long max_addr)
+{
+ unsigned long alloc;
+
+ alloc = __lmb_alloc_base(size, align, max_addr);
+
+ if (alloc == 0)
+ panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
+ size, max_addr);
+
+ return alloc;
+}
+
+unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
+ unsigned long max_addr)
+{
+ long i, j;
+ unsigned long base = 0;
+
+ BUG_ON(0 == size);
+
+#ifdef CONFIG_PPC32
+ /* On 32-bit, make sure we allocate lowmem */
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ max_addr = __max_low_memory;
+#endif
+ for (i = lmb.memory.cnt-1; i >= 0; i--) {
+ unsigned long lmbbase = lmb.memory.region[i].base;
+ unsigned long lmbsize = lmb.memory.region[i].size;
+
+ if (max_addr == LMB_ALLOC_ANYWHERE)
+ base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
+ else if (lmbbase < max_addr) {
+ base = min(lmbbase + lmbsize, max_addr);
+ base = _ALIGN_DOWN(base - size, align);
+ } else
+ continue;
+
+ while ((lmbbase <= base) &&
+ ((j = lmb_overlaps_region(&lmb.reserved, base, size))
+ >= 0))
+ base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
+ align);
+
+ if ((base != 0) && (lmbbase <= base))
+ break;
+ }
+
+ if (i < 0)
+ return 0;
+
+ lmb_add_region(&lmb.reserved, base, size);
+
+ return base;
+}
+
+/* You must call lmb_analyze() before this. */
+unsigned long __init lmb_phys_mem_size(void)
+{
+ return lmb.memory.size;
+}
+
+unsigned long __init lmb_end_of_DRAM(void)
+{
+ int idx = lmb.memory.cnt - 1;
+
+ return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
+}
+
+/* You must call lmb_analyze() after this. */
+void __init lmb_enforce_memory_limit(unsigned long memory_limit)
+{
+ unsigned long i, limit;
+ struct lmb_property *p;
+
+ if (!memory_limit)
+ return;
+
+ /* Truncate the lmb regions to satisfy the memory limit. */
+ limit = memory_limit;
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ if (limit > lmb.memory.region[i].size) {
+ limit -= lmb.memory.region[i].size;
+ continue;
+ }
+
+ lmb.memory.region[i].size = limit;
+ lmb.memory.cnt = i + 1;
+ break;
+ }
+
+ if (lmb.memory.region[0].size < lmb.rmo_size)
+ lmb.rmo_size = lmb.memory.region[0].size;
+
+ /* And truncate any reserves above the limit also. */
+ for (i = 0; i < lmb.reserved.cnt; i++) {
+ p = &lmb.reserved.region[i];
+
+ if (p->base > memory_limit)
+ p->size = 0;
+ else if ((p->base + p->size) > memory_limit)
+ p->size = memory_limit - p->base;
+
+ if (p->size == 0) {
+ lmb_remove_region(&lmb.reserved, i);
+ i--;
+ }
+ }
+}
diff --git a/include/asm-microblaze/lmb.h b/include/asm-microblaze/lmb.h
new file mode 100644
index 0000000..f27bb13
--- /dev/null
+++ b/include/asm-microblaze/lmb.h
@@ -0,0 +1,84 @@
+/*
+ * include/asm-microblaze/lmb.h
+ *
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 2001 Peter Bergner, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_LMB_H
+#define _ASM_LMB_H
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <asm/prom.h>
+
+#define MAX_LMB_REGIONS 128
+
+struct lmb_property {
+ unsigned long base;
+ unsigned long size;
+};
+
+struct lmb_region {
+ unsigned long cnt;
+ unsigned long size;
+ struct lmb_property region[MAX_LMB_REGIONS+1];
+};
+
+struct lmb {
+ unsigned long debug;
+ unsigned long rmo_size;
+ struct lmb_region memory;
+ struct lmb_region reserved;
+};
+
+extern struct lmb lmb;
+
+extern void __init lmb_init(void);
+extern void __init lmb_analyze(void);
+extern long __init lmb_add(unsigned long base, unsigned long size);
+extern long __init lmb_reserve(unsigned long base, unsigned long size);
+extern unsigned long __init lmb_alloc(unsigned long size, unsigned long align);
+extern unsigned long __init lmb_alloc_base(unsigned long size,
+ unsigned long align, unsigned long max_addr);
+extern unsigned long __init __lmb_alloc_base(unsigned long size,
+ unsigned long align, unsigned long max_addr);
+extern unsigned long __init lmb_phys_mem_size(void);
+extern unsigned long __init lmb_end_of_DRAM(void);
+extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
+extern long __init lmb_overlaps_region(struct lmb_region *rgn,
+ unsigned long base, unsigned long size);
+
+extern void lmb_dump_all(void);
+
+static inline unsigned long
+lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
+{
+ return type->region[region_nr].size;
+}
+static inline unsigned long
+lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
+{
+ return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
+}
+static inline unsigned long
+lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+ return type->region[region_nr].base >> PAGE_SHIFT;
+}
+static inline unsigned long
+lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+ return lmb_start_pfn(type, region_nr) +
+ lmb_size_pages(type, region_nr);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_LMB_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 12/52] [microblaze] lmb support
2008-01-24 15:02 ` [PATCH 12/52] [microblaze] lmb support monstr
@ 2008-01-27 12:51 ` Jan Engelhardt
0 siblings, 0 replies; 67+ messages in thread
From: Jan Engelhardt @ 2008-01-27 12:51 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Jan 24 2008 16:02, monstr@monstr.eu wrote:
>+
>+#define DEBUG
>+
>+#ifdef DEBUG
>+#define DBG(fmt...) printk(fmt)
>+#else
>+#define DBG(fmt...)
>+#endif
Phew, don't reinvent the wheel - use the existing pr_debug() instead.
>+static unsigned long __init lmb_addrs_overlap(unsigned long base1,
>+ unsigned long size1, unsigned long base2, unsigned long size2)
>+{
>+ return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
return base1 < base2 + size2 && base2 < base1 + size1;
>+}
Operator precedence makes it possible; you could omit a lot of () in the code.
(Also try checkpatch.pl to get to know of other style 'errors')
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 13/52] [microblaze] PVR support, cpuinfo support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (2 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 12/52] [microblaze] lmb support monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 14/52] [microblaze] defconfig file monstr
` (47 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/cpu/mb.c | 115 ++++++++++++++++++++++++++++++++++++++
arch/microblaze/kernel/cpu/pvr.c | 83 +++++++++++++++++++++++++++
2 files changed, 198 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/cpu/mb.c
create mode 100644 arch/microblaze/kernel/cpu/pvr.c
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
new file mode 100644
index 0000000..2e68c3f
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -0,0 +1,115 @@
+/*
+ * arch/microblaze/kernel/cpu/mb.c
+ *
+ * CPU-version specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 PetaLogix
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+
+#include <asm/cpuinfo.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/bug.h>
+#include <asm/param.h>
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ int count = 0;
+ char *fpga_family = "Unknown";
+ char *cpu_ver = "Unknown";
+ int i;
+
+ /* Denormalised to get the fpga family string */
+ for (i = 0; family_string_lookup[i].s != NULL; i++) {
+ if (cpuinfo->fpga_family_code == family_string_lookup[i].k) {
+ fpga_family = family_string_lookup[i].s;
+ break;
+ }
+ }
+
+ /* Denormalised to get the hw version string */
+ for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+ if (cpuinfo->ver_code == cpu_ver_lookup[i].k) {
+ cpu_ver = cpu_ver_lookup[i].s;
+ break;
+ }
+ }
+
+ count = seq_printf(m,
+ "CPU-Family: MicroBlaze\n"
+ "FPGA-Arch: %s\n"
+ "CPU-Ver: %s\n"
+ "CPU-MHz: %d.%02d\n"
+ "BogoMips: %lu.%02lu\n",
+ fpga_family,
+ cpu_ver,
+ cpuinfo->cpu_clock_freq /
+ 1000000,
+ cpuinfo->cpu_clock_freq %
+ 1000000,
+ loops_per_jiffy / (500000 / HZ),
+ (loops_per_jiffy / (5000 / HZ)) % 100);
+
+ count += seq_printf(m,
+ "HW-Div:\t\t%s\n"
+ "HW-Shift:\t%s\n",
+ cpuinfo->use_divider ? "yes" : "no",
+ cpuinfo->use_barrel ? "yes" : "no");
+
+ if (cpuinfo->use_icache)
+ count += seq_printf(m,
+ "Icache:\t\t%ukB\n",
+ cpuinfo->icache_size >> 10);
+ else
+ count += seq_printf(m, "Icache:\t\tno\n");
+
+ if (cpuinfo->use_dcache)
+ count += seq_printf(m,
+ "Dcache:\t\t%ukB\n",
+ cpuinfo->dcache_size >> 10);
+ else
+ count += seq_printf(m, "Dcache:\t\tno\n");
+
+ count += seq_printf(m,
+ "HW-Debug:\t%s\n",
+ cpuinfo->hw_debug ? "yes" : "no");
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ int i = *pos;
+
+ return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
new file mode 100644
index 0000000..37e3a45
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -0,0 +1,83 @@
+/*
+ * arch/microblaze/kernel/cpu/pvr.c
+ *
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * (C) 2007 Michal Simek <monstr@monstr.eu>
+ * (C) 2007 John Williams <john.williams@petalogix.com>
+ * (C) 2007 PetaLogix
+ */
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <asm/system.h>
+#include <asm/exceptions.h>
+#include <asm/pvr.h>
+
+/*
+ * Until we get an assembler that knows about the pvr registers,
+ * this horrible cruft will have to do.
+ * That hardcoded opcode is mfs r3, rpvrNN
+ */
+
+#define get_single_pvr(pvrid, val) \
+{ \
+ register unsigned tmp __asm__("r3"); \
+ tmp = 0x0; /* Prevent warning about unused */ \
+ __asm__ __volatile__ ( \
+ ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \
+ : "=r" (tmp):: "memory"); \
+ val = tmp; \
+}
+
+/*
+ * Does the CPU support the PVR register?
+ * return value:
+ * 0: no PVR
+ * 1: simple PVR
+ * 2: full PVR
+ *
+ * This must work on all CPU versions, including those before the
+ * PVR was even an option.
+ */
+
+int cpu_has_pvr(void)
+{
+ unsigned flags;
+ unsigned pvr0;
+ int ret = 0;
+
+ local_irq_save(flags);
+
+ /* PVR bit in MSR tells us if there is any support */
+ if (!(flags & PVR_MSR_BIT))
+ goto out;
+
+ get_single_pvr(0x00, pvr0);
+ pr_debug("%s: pvr0 is 0x%08x\n", __FUNCTION__, pvr0);
+
+ if (pvr0 & PVR0_PVR_FULL_MASK)
+ ret = 2;
+ else
+ ret = 1;
+
+out:
+ local_irq_restore(flags);
+ return ret;
+}
+
+void get_pvr(struct pvr_s *p)
+{
+ get_single_pvr(0, p->pvr[0]);
+ get_single_pvr(1, p->pvr[1]);
+ get_single_pvr(2, p->pvr[2]);
+ get_single_pvr(3, p->pvr[3]);
+ get_single_pvr(4, p->pvr[4]);
+ get_single_pvr(5, p->pvr[5]);
+ get_single_pvr(6, p->pvr[6]);
+ get_single_pvr(7, p->pvr[7]);
+ get_single_pvr(8, p->pvr[8]);
+ get_single_pvr(9, p->pvr[9]);
+ get_single_pvr(10, p->pvr[10]);
+ get_single_pvr(11, p->pvr[11]);
+}
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 14/52] [microblaze] defconfig file
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (3 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 13/52] [microblaze] PVR support, cpuinfo support monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 15/52] [microblaze] assembler files head.S, entry.S, monstr
` (46 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/defconfig | 449 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 449 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/defconfig
diff --git a/arch/microblaze/defconfig b/arch/microblaze/defconfig
new file mode 100644
index 0000000..ea25a7b
--- /dev/null
+++ b/arch/microblaze/defconfig
@@ -0,0 +1,449 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc5
+# Fri Dec 21 12:18:34 2007
+#
+CONFIG_MICROBLAZE=y
+# CONFIG_MMU is not set
+# CONFIG_SWAP is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_PCI is not set
+CONFIG_UID16=y
+CONFIG_DEFCONFIG_LIST="arch/$ARCH/defconfig"
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+# CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+CONFIG_ANON_INODES=y
+# CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform options
+#
+CONFIG_PLATFORM_GENERIC=y
+CONFIG_ALLOW_EDIT_AUTO=y
+
+#
+# Automatic platform settings from Kconfig.auto
+#
+CONFIG_KERNEL_BASE_ADDR=0x44000000
+CONFIG_XILINX_ERAM_SIZE=0x02000000
+
+#
+# Definitions for MICROBLAZE0
+#
+CONFIG_XILINX_MICROBLAZE0_FAMILY="spartan3e"
+CONFIG_XILINX_MICROBLAZE0_HW_VER="5.00.c"
+CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
+CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
+CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=1
+CONFIG_XILINX_MICROBLAZE0_USE_FPU=0
+
+#
+# Processor type and features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_XILINX_UNCACHED_SHADOW is not set
+# CONFIG_LARGE_ALLOCS is not set
+
+#
+# Boot options
+#
+CONFIG_CMDLINE="root=/dev/mtdblock0"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_OF=y
+CONFIG_OF_DEVICE=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Exectuable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SAMPLES is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_UARTLITE_ADDRESS=0x40600000
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 15/52] [microblaze] assembler files head.S, entry.S, ...
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (4 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 14/52] [microblaze] defconfig file monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 16/52] [microblaze] supported function for memory - kernel/lib monstr
` (45 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/entry.S | 597 ++++++++++++++++++++++++++++++++
arch/microblaze/kernel/head.S | 40 +++
arch/microblaze/kernel/syscall_table.S | 328 ++++++++++++++++++
arch/microblaze/kernel/vmlinux.lds.S | 145 ++++++++
4 files changed, 1110 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/entry.S
create mode 100644 arch/microblaze/kernel/head.S
create mode 100644 arch/microblaze/kernel/syscall_table.S
create mode 100644 arch/microblaze/kernel/vmlinux.lds.S
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
new file mode 100644
index 0000000..d0b487b
--- /dev/null
+++ b/arch/microblaze/kernel/entry.S
@@ -0,0 +1,597 @@
+/*
+ * arch/microblaze/kernel/entry.S
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/asm-offsets.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#include <asm/percpu.h>
+#include <asm/signal.h>
+
+#define PER_CPU(var) per_cpu__##var
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ .macro disable_irq
+ msrclr r0, MSR_IE
+ .endm
+
+ .macro enable_irq
+ msrset r0, MSR_IE
+ .endm
+
+ .macro clear_bip
+ msrclr r0, MSR_BIP
+ .endm
+#else
+ .macro disable_irq
+ mfs r11, rmsr
+ andi r11, r11, ~MSR_IE
+ mts rmsr, r11
+ .endm
+
+ .macro enable_irq
+ mfs r11, rmsr
+ ori r11, r11, MSR_IE
+ mts rmsr, r11
+ .endm
+
+ .macro clear_bip
+ mfs r11, rmsr
+ andi r11, r11, ~MSR_BIP
+ mts rmsr, r11
+ .endm
+#endif
+
+ENTRY(_interrupt)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+ beqid r11, 1f
+ nop
+ brid 2f /* jump over */
+ addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */
+1: /* switch to kernel stack */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ /* calculate kernel stack pointer */
+ addik r1, r1, THREAD_SIZE - PT_SIZE
+2:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3
+ swi r4, r1, PT_R4
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ swi r14, r1, PT_R14
+ swi r14, r1, PT_PC
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* prepare the link register, the argument and jump */
+ la r15, r0, ret_from_intr - 8
+ addk r6, r0, r15
+ braid do_IRQ
+ add r5, r0, r1
+
+ret_from_intr:
+ lwi r11, r1, PT_MODE
+ bneid r11, 3f
+
+ lwi r6, r31, TS_THREAD_INFO /* get thread info */
+ lwi r19, r6, TI_FLAGS /* get flags in thread info */
+ /* do an extra work if any bits are set */
+
+ andi r11, r19, _TIF_NEED_RESCHED
+ beqi r11, 1f
+ bralid r15, schedule
+ nop
+1: andi r11, r19, _TIF_SIGPENDING
+ beqid r11, no_intr_reshed
+ addk r5, r1, r0
+ addk r7, r0, r0
+ bralid r15, do_signal
+ addk r6, r0, r0
+
+no_intr_reshed:
+ /* save mode indicator */
+ lwi r11, r1, PT_MODE
+3:
+ swi r11, r0, PER_CPU(KM)
+
+ /* save r31 */
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+restore_context:
+ /* special purpose registers */
+ lwi r11, r1, PT_FSR
+ mts rfsr, r11
+ lwi r11, r1, PT_ESR
+ mts resr, r11
+ lwi r11, r1, PT_EAR
+ mts rear, r11
+ lwi r11, r1, PT_MSR
+ mts rmsr, r11
+
+ lwi r31, r1, PT_R31
+ lwi r30, r1, PT_R30
+ lwi r29, r1, PT_R29
+ lwi r28, r1, PT_R28
+ lwi r27, r1, PT_R27
+ lwi r26, r1, PT_R26
+ lwi r25, r1, PT_R25
+ lwi r24, r1, PT_R24
+ lwi r23, r1, PT_R23
+ lwi r22, r1, PT_R22
+ lwi r21, r1, PT_R21
+ lwi r20, r1, PT_R20
+ lwi r19, r1, PT_R19
+ lwi r18, r1, PT_R18
+ lwi r17, r1, PT_R17
+ lwi r16, r1, PT_R16
+ lwi r15, r1, PT_R15
+ lwi r14, r1, PT_PC
+ lwi r13, r1, PT_R13
+ lwi r12, r1, PT_R12
+ lwi r11, r1, PT_R11
+ lwi r10, r1, PT_R10
+ lwi r9, r1, PT_R9
+ lwi r8, r1, PT_R8
+ lwi r7, r1, PT_R7
+ lwi r6, r1, PT_R6
+ lwi r5, r1, PT_R5
+ lwi r4, r1, PT_R4
+ lwi r3, r1, PT_R3
+ lwi r2, r1, PT_R2
+ lwi r1, r1, PT_R1
+ rtid r14, 0
+ nop
+
+ENTRY(_reset)
+ brai 0;
+
+ENTRY(_user_exception)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+ beqid r11, 1f /* Already in kernel mode? */
+ nop
+ brid 2f /* jump over */
+ addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */
+1: /* Switch to kernel stack */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ /* calculate kernel stack pointer */
+ addik r1, r1, THREAD_SIZE - PT_SIZE
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+2:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ /* save them on stack */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+ swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ /* r12: _always_ in clobber list; see unistd.h */
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ /* r14: _always_ in clobber list; see unistd.h */
+ swi r14, r1, PT_R14
+ /* but we want to return to the next inst. */
+ addik r14, r14, 0x4
+ swi r14, r1, PT_PC /* increment by 4 and store in pc */
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+
+ disable_irq
+ nop /* make sure IE bit is in effect */
+ clear_bip /* once IE is in effect it is safe to clear BIP */
+ nop
+
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* re-enable interrupts now we are in kernel mode */
+ enable_irq
+
+ /* See if the system call number is valid. */
+ addi r11, r12, -NR_syscalls
+ bgei r11, 1f /* return to user if not valid */
+ /* Figure out which function to use for this system call. */
+ /* Note Microblaze barrel shift is optional, so don't rely on it */
+ add r12, r12, r12 /* convert num -> ptr */
+ add r12, r12, r12
+ lwi r12, r12, sys_call_table /* Get function pointer */
+ la r15, r0, ret_to_user-8 /* set return address */
+ bra r12 /* Make the system call. */
+ bri 0 /* won't reach here */
+1:
+ brid ret_to_user /* jump to syscall epilogue */
+ addi r3, r0, -ENOSYS /* set errno in delay slot */
+
+/*
+ * Debug traps are like a system call, but entered via brki r14, 0x60
+ * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
+ * will handle the rest
+ */
+ENTRY(_debug_exception)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+//save_context:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ /* save them on stack */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+ swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ /* r12: _always_ in clobber list; see unistd.h */
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ /* r14: _always_ in clobber list; see unistd.h */
+ swi r14, r1, PT_R14
+ swi r14, r1, PT_PC /* Will return to interrupted instruction */
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+
+ disable_irq
+ nop /* make sure IE bit is in effect */
+ clear_bip /* once IE is in effect it is safe to clear BIP */
+ nop
+
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* re-enable interrupts now we are in kernel mode */
+ enable_irq
+
+ addi r5, r0, SIGTRAP /* sending the trap signal */
+ add r6, r0, r31 /* to current */
+ bralid r15, send_sig
+ add r7, r0, r0 /* 3rd param zero */
+
+ /* Restore r3/r4 to work around how ret_to_user works */
+ lwi r3, r1, PT_R3
+ lwi r4, r1, PT_R4
+ bri ret_to_user
+
+ENTRY(_break)
+ bri 0
+
+/* struct task_struct *_switch_to(struct thread_info *prev,
+ struct thread_info *next); */
+ENTRY(_switch_to)
+ /* prepare return value */
+ addk r3, r0, r31
+
+ /* save registers in cpu_context */
+ /* use r11 and r12, volatile registers, as temp register */
+ addik r11, r5, TI_CPU_CONTEXT
+ swi r1, r11, CC_SP
+ swi r2, r11, CC_R2
+ /* skip volatile registers.
+ * they are saved on stack when we jumped to _switch_to() */
+ /* dedicated registers */
+ swi r13, r11, CC_R13
+ swi r14, r11, CC_R14
+ swi r15, r11, CC_R15
+ swi r16, r11, CC_R16
+ swi r17, r11, CC_R17
+ swi r18, r11, CC_R18
+ /* save non-volatile registers */
+ swi r19, r11, CC_R19
+ swi r20, r11, CC_R20
+ swi r21, r11, CC_R21
+ swi r22, r11, CC_R22
+ swi r23, r11, CC_R23
+ swi r24, r11, CC_R24
+ swi r25, r11, CC_R25
+ swi r26, r11, CC_R26
+ swi r27, r11, CC_R27
+ swi r28, r11, CC_R28
+ swi r29, r11, CC_R29
+ swi r30, r11, CC_R30
+ /* special purpose registers */
+ mfs r12, rmsr
+ swi r12, r11, CC_MSR
+ mfs r12, rear
+ swi r12, r11, CC_EAR
+ mfs r12, resr
+ swi r12, r11, CC_ESR
+ mfs r12, rfsr
+ swi r12, r11, CC_FSR
+
+ /* update r31, the current */
+ lwi r31, r6, TI_TASK
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+
+ /* get new process' cpu context and restore */
+ addik r11, r6, TI_CPU_CONTEXT
+
+ /* special purpose registers */
+ lwi r12, r11, CC_FSR
+ mts rfsr, r12
+ lwi r12, r11, CC_ESR
+ mts resr, r12
+ lwi r12, r11, CC_EAR
+ mts rear, r12
+ lwi r12, r11, CC_MSR
+ mts rmsr, r12
+ /* non-volatile registers */
+ lwi r30, r11, CC_R30
+ lwi r29, r11, CC_R29
+ lwi r28, r11, CC_R28
+ lwi r27, r11, CC_R27
+ lwi r26, r11, CC_R26
+ lwi r25, r11, CC_R25
+ lwi r24, r11, CC_R24
+ lwi r23, r11, CC_R23
+ lwi r22, r11, CC_R22
+ lwi r21, r11, CC_R21
+ lwi r20, r11, CC_R20
+ lwi r19, r11, CC_R19
+ /* dedicated registers */
+ lwi r18, r11, CC_R18
+ lwi r17, r11, CC_R17
+ lwi r16, r11, CC_R16
+ lwi r15, r11, CC_R15
+ lwi r14, r11, CC_R14
+ lwi r13, r11, CC_R13
+ /* skip volatile registers */
+ lwi r2, r11, CC_R2
+ lwi r1, r11, CC_SP
+
+ rtsd r15, 8
+ nop
+
+ENTRY(ret_from_fork)
+ addk r5, r0, r3
+ addk r6, r0, r1
+ brlid r15, schedule_tail
+ nop
+ swi r31, r1, PT_R31 /* save r31 in user context. */
+ /* will soon be restored to r31 in ret_to_user */
+ addk r3, r0, r0
+ brid ret_to_user
+ nop
+
+work_pending:
+ andi r11, r19, _TIF_NEED_RESCHED
+ beqi r11, 1f
+ bralid r15, schedule
+ nop
+1: andi r11, r19, _TIF_SIGPENDING
+ beqi r11, no_work_pending
+ addk r5, r1, r0
+ addik r7, r0, 1
+ bralid r15, do_signal
+ addk r6, r0, r0
+ bri no_work_pending
+
+ENTRY(ret_to_user)
+ disable_irq
+
+ swi r4, r1, PT_R4 /* return val */
+ swi r3, r1, PT_R3 /* return val */
+
+ lwi r6, r31, TS_THREAD_INFO /* get thread info */
+ lwi r19, r6, TI_FLAGS /* get flags in thread info */
+ bnei r19, work_pending /* do an extra work if any bits are set */
+no_work_pending:
+ disable_irq
+
+ /* save r31 */
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* save mode indicator */
+ lwi r18, r1, PT_MODE
+ swi r18, r0, PER_CPU(KM)
+//restore_context:
+ /* special purpose registers */
+ lwi r18, r1, PT_FSR
+ mts rfsr, r18
+ lwi r18, r1, PT_ESR
+ mts resr, r18
+ lwi r18, r1, PT_EAR
+ mts rear, r18
+ lwi r18, r1, PT_MSR
+ mts rmsr, r18
+
+ lwi r31, r1, PT_R31
+ lwi r30, r1, PT_R30
+ lwi r29, r1, PT_R29
+ lwi r28, r1, PT_R28
+ lwi r27, r1, PT_R27
+ lwi r26, r1, PT_R26
+ lwi r25, r1, PT_R25
+ lwi r24, r1, PT_R24
+ lwi r23, r1, PT_R23
+ lwi r22, r1, PT_R22
+ lwi r21, r1, PT_R21
+ lwi r20, r1, PT_R20
+ lwi r19, r1, PT_R19
+ lwi r18, r1, PT_R18
+ lwi r17, r1, PT_R17
+ lwi r16, r1, PT_R16
+ lwi r15, r1, PT_R15
+ lwi r14, r1, PT_PC
+ lwi r13, r1, PT_R13
+ lwi r12, r1, PT_R12
+ lwi r11, r1, PT_R11
+ lwi r10, r1, PT_R10
+ lwi r9, r1, PT_R9
+ lwi r8, r1, PT_R8
+ lwi r7, r1, PT_R7
+ lwi r6, r1, PT_R6
+ lwi r5, r1, PT_R5
+ lwi r4, r1, PT_R4 /* return val */
+ lwi r3, r1, PT_R3 /* return val */
+ lwi r2, r1, PT_R2
+ lwi r1, r1, PT_R1
+
+ rtid r14, 0
+ nop
+
+sys_vfork_wrapper:
+ brid sys_vfork
+ addk r5, r1, r0
+
+sys_clone_wrapper:
+ brid sys_clone
+ addk r7, r1, r0
+
+sys_execve_wrapper:
+ brid sys_execve
+ addk r8, r1, r0
+
+sys_sigreturn_wrapper:
+ brid sys_sigreturn
+ addk r5, r1, r0
+
+sys_rt_sigreturn_wrapper:
+ brid sys_rt_sigreturn
+ addk r5, r1, r0
+
+sys_sigsuspend_wrapper:
+ brid sys_rt_sigsuspend
+ addk r6, r1, r0
+
+sys_rt_sigsuspend_wrapper:
+ brid sys_rt_sigsuspend
+ addk r7, r1, r0
+
+ /* Interrupt vector table */
+ .section .init.ivt, "ax"
+ .org 0x0
+ brai _reset
+ brai _user_exception
+ brai _interrupt
+ brai _break
+ brai _hw_exception_handler
+ .org 0x60
+ brai _debug_exception
+
+.section .rodata,"a"
+#include "syscall_table.S"
+
+syscall_table_size=(.-sys_call_table)
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
new file mode 100644
index 0000000..8ca148b
--- /dev/null
+++ b/arch/microblaze/kernel/head.S
@@ -0,0 +1,40 @@
+/*
+ * arch/microblaze/kernel/head.S
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+
+ .text
+ENTRY(_start)
+ mfs r1, rmsr
+ andi r1, r1, ~2
+ mts rmsr, r1
+
+ /* Initialize small data anchors */
+ la r13, r0, _KERNEL_SDA_BASE_
+ la r2, r0, _KERNEL_SDA2_BASE_
+
+ /* Initialize stack pointer */
+ la r1, r0, init_thread_union + THREAD_SIZE - 4
+
+ /* Initialize r31 with current task address */
+ la r31, r0, init_task
+
+ /* Call platform dependent initialize function.
+ * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
+ * the function. */
+ la r8, r0, machine_early_init
+ brald r15, r8
+ nop
+
+ la r15, r0, machine_halt
+ braid start_kernel
+ nop
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
new file mode 100644
index 0000000..3ff41f8
--- /dev/null
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -0,0 +1,328 @@
+ENTRY(sys_call_table)
+ .long sys_restart_syscall /* 0 - old "setup()" system call,
+ * used for restarting */
+ .long sys_exit
+ .long sys_ni_syscall /* was fork */
+ .long sys_read
+ .long sys_write
+ .long sys_open /* 5 */
+ .long sys_close
+ .long sys_waitpid
+ .long sys_creat
+ .long sys_link
+ .long sys_unlink /* 10 */
+ .long sys_execve_wrapper
+ .long sys_chdir
+ .long sys_time
+ .long sys_mknod
+ .long sys_chmod /* 15 */
+ .long sys_lchown16
+ .long sys_ni_syscall /* old break syscall holder */
+ .long sys_ni_syscall /* stat */
+ .long sys_lseek
+ .long sys_getpid /* 20 */
+ .long sys_mount
+ .long sys_oldumount
+ .long sys_setuid16
+ .long sys_getuid16
+ .long sys_stime /* 25 */
+ .long sys_ptrace
+ .long sys_alarm
+ .long sys_ni_syscall /* fstat */
+ .long sys_pause
+ .long sys_utime /* 30 */
+ .long sys_ni_syscall /* old stty syscall holder */
+ .long sys_ni_syscall /* old gtty syscall holder */
+ .long sys_access
+ .long sys_nice
+ .long sys_ni_syscall /* 35 - old ftime syscall holder */
+ .long sys_sync
+ .long sys_kill
+ .long sys_rename
+ .long sys_mkdir
+ .long sys_rmdir /* 40 */
+ .long sys_dup
+ .long sys_pipe
+ .long sys_times
+ .long sys_ni_syscall /* old prof syscall holder */
+ .long sys_brk /* 45 */
+ .long sys_setgid16
+ .long sys_getgid16
+ .long sys_signal
+ .long sys_geteuid16
+ .long sys_getegid16 /* 50 */
+ .long sys_acct
+ .long sys_umount /* recycled never used phys() */
+ .long sys_ni_syscall /* old lock syscall holder */
+ .long sys_ioctl
+ .long sys_fcntl /* 55 */
+ .long sys_ni_syscall /* old mpx syscall holder */
+ .long sys_setpgid
+ .long sys_ni_syscall /* old ulimit syscall holder */
+ .long sys_ni_syscall /* olduname */
+ .long sys_umask /* 60 */
+ .long sys_chroot
+ .long sys_ustat
+ .long sys_dup2
+ .long sys_getppid
+ .long sys_getpgrp /* 65 */
+ .long sys_setsid
+ .long sys_sigaction
+ .long sys_sgetmask
+ .long sys_ssetmask
+ .long sys_setreuid16 /* 70 */
+ .long sys_setregid16
+ .long sys_sigsuspend_wrapper
+ .long sys_sigpending
+ .long sys_sethostname
+ .long sys_setrlimit /* 75 */
+ .long sys_ni_syscall /* old_getrlimit */
+ .long sys_getrusage
+ .long sys_gettimeofday
+ .long sys_settimeofday
+ .long sys_getgroups16 /* 80 */
+ .long sys_setgroups16
+ .long sys_ni_syscall /* old_select */
+ .long sys_symlink
+ .long sys_ni_syscall /* lstat */
+ .long sys_readlink /* 85 */
+ .long sys_uselib
+ .long sys_swapon
+ .long sys_reboot
+ .long sys_ni_syscall /* old_readdir */
+ .long sys_mmap /* 90 */ /* old_mmap */
+ .long sys_munmap
+ .long sys_truncate
+ .long sys_ftruncate
+ .long sys_fchmod
+ .long sys_fchown16 /* 95 */
+ .long sys_getpriority
+ .long sys_setpriority
+ .long sys_ni_syscall /* old profil syscall holder */
+ .long sys_statfs
+ .long sys_fstatfs /* 100 */
+ .long sys_ni_syscall /* ioperm */
+ .long sys_socketcall
+ .long sys_syslog
+ .long sys_setitimer
+ .long sys_getitimer /* 105 */
+ .long sys_newstat
+ .long sys_newlstat
+ .long sys_newfstat
+ .long sys_ni_syscall /* uname */
+ .long sys_ni_syscall /* 110 */ /* iopl */
+ .long sys_vhangup
+ .long sys_ni_syscall /* old "idle" system call */
+ .long sys_ni_syscall /* old sys_vm86old */
+ .long sys_wait4
+ .long sys_swapoff /* 115 */
+ .long sys_sysinfo
+ .long sys_ipc
+ .long sys_fsync
+ .long sys_sigreturn_wrapper
+ .long sys_clone_wrapper /* 120 */
+ .long sys_setdomainname
+ .long sys_newuname
+ .long sys_ni_syscall /* modify_ldt */
+ .long sys_adjtimex
+ .long sys_ni_syscall /* 125: sys_mprotect */
+ .long sys_sigprocmask
+ .long sys_ni_syscall /* old "create_module" */
+ .long sys_init_module
+ .long sys_delete_module
+ .long sys_ni_syscall /* 130: old "get_kernel_syms" */
+ .long sys_quotactl
+ .long sys_getpgid
+ .long sys_fchdir
+ .long sys_bdflush
+ .long sys_sysfs /* 135 */
+ .long sys_personality
+ .long sys_ni_syscall /* reserved for afs_syscall */
+ .long sys_setfsuid16
+ .long sys_setfsgid16
+ .long sys_llseek /* 140 */
+ .long sys_getdents
+ .long sys_select
+ .long sys_flock
+ .long sys_ni_syscall /* sys_msync */
+ .long sys_readv /* 145 */
+ .long sys_writev
+ .long sys_getsid
+ .long sys_fdatasync
+ .long sys_sysctl
+ .long sys_ni_syscall /* 150: sys_mlock */
+ .long sys_ni_syscall /* sys_munlock */
+ .long sys_ni_syscall /* sys_mlockall */
+ .long sys_ni_syscall /* sys_munlockall */
+ .long sys_sched_setparam
+ .long sys_sched_getparam /* 155 */
+ .long sys_sched_setscheduler
+ .long sys_sched_getscheduler
+ .long sys_sched_yield
+ .long sys_sched_get_priority_max
+ .long sys_sched_get_priority_min /* 160 */
+ .long sys_sched_rr_get_interval
+ .long sys_nanosleep
+ .long sys_ni_syscall /* sys_mremap */
+ .long sys_setresuid16
+ .long sys_getresuid16 /* 165 */
+ .long sys_ni_syscall /* sys_vm86 */
+ .long sys_ni_syscall /* Old sys_query_module */
+ .long sys_poll
+ .long sys_nfsservctl
+ .long sys_setresgid16 /* 170 */
+ .long sys_getresgid16
+ .long sys_prctl
+ .long sys_rt_sigreturn_wrapper
+ .long sys_rt_sigaction
+ .long sys_rt_sigprocmask /* 175 */
+ .long sys_rt_sigpending
+ .long sys_rt_sigtimedwait
+ .long sys_rt_sigqueueinfo
+ .long sys_rt_sigsuspend_wrapper
+ .long sys_pread64 /* 180 */
+ .long sys_pwrite64
+ .long sys_chown16
+ .long sys_getcwd
+ .long sys_capget
+ .long sys_capset /* 185 */
+ .long sys_ni_syscall /* sigaltstack */
+ .long sys_sendfile
+ .long sys_ni_syscall /* reserved for streams1 */
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork_wrapper /* 190 */
+ .long sys_getrlimit
+ .long sys_mmap2 /* mmap2 */
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+ .long sys_lstat64
+ .long sys_fstat64
+ .long sys_lchown
+ .long sys_getuid
+ .long sys_getgid /* 200 */
+ .long sys_geteuid
+ .long sys_getegid
+ .long sys_setreuid
+ .long sys_setregid
+ .long sys_getgroups /* 205 */
+ .long sys_setgroups
+ .long sys_fchown
+ .long sys_setresuid
+ .long sys_getresuid
+ .long sys_setresgid /* 210 */
+ .long sys_getresgid
+ .long sys_chown
+ .long sys_setuid
+ .long sys_setgid
+ .long sys_setfsuid /* 215 */
+ .long sys_setfsgid
+ .long sys_pivot_root
+ .long sys_ni_syscall /* sys_mincore */
+ .long sys_ni_syscall /* sys_madvise */
+ .long sys_getdents64 /* 220 */
+ .long sys_fcntl64
+ .long sys_ni_syscall /* reserved for TUX */
+ .long sys_ni_syscall
+ .long sys_gettid
+ .long sys_readahead /* 225 */
+ .long sys_setxattr
+ .long sys_lsetxattr
+ .long sys_fsetxattr
+ .long sys_getxattr
+ .long sys_lgetxattr /* 230 */
+ .long sys_fgetxattr
+ .long sys_listxattr
+ .long sys_llistxattr
+ .long sys_flistxattr
+ .long sys_removexattr /* 235 */
+ .long sys_lremovexattr
+ .long sys_fremovexattr
+ .long sys_tkill
+ .long sys_sendfile64
+ .long sys_futex /* 240 */
+ .long sys_sched_setaffinity
+ .long sys_sched_getaffinity
+ .long sys_ni_syscall /* set_thread_area */
+ .long sys_ni_syscall /* get_thread_area */
+ .long sys_io_setup /* 245 */
+ .long sys_io_destroy
+ .long sys_io_getevents
+ .long sys_io_submit
+ .long sys_io_cancel
+ .long sys_fadvise64 /* 250 */
+ .long sys_ni_syscall
+ .long sys_exit_group
+ .long sys_lookup_dcookie
+ .long sys_epoll_create
+ .long sys_epoll_ctl /* 255 */
+ .long sys_epoll_wait
+ .long sys_ni_syscall /* sys_remap_file_pages */
+ .long sys_set_tid_address
+ .long sys_timer_create
+ .long sys_timer_settime /* 260 */
+ .long sys_timer_gettime
+ .long sys_timer_getoverrun
+ .long sys_timer_delete
+ .long sys_clock_settime
+ .long sys_clock_gettime /* 265 */
+ .long sys_clock_getres
+ .long sys_clock_nanosleep
+ .long sys_statfs64
+ .long sys_fstatfs64
+ .long sys_tgkill /* 270 */
+ .long sys_utimes
+ .long sys_fadvise64_64
+ .long sys_ni_syscall /* sys_vserver */
+ .long sys_mbind
+ .long sys_get_mempolicy
+ .long sys_set_mempolicy
+ .long sys_mq_open
+ .long sys_mq_unlink
+ .long sys_mq_timedsend
+ .long sys_mq_timedreceive /* 280 */
+ .long sys_mq_notify
+ .long sys_mq_getsetattr
+ .long sys_kexec_load
+ .long sys_waitid
+ .long sys_ni_syscall /* 285 */ /* available */
+ .long sys_add_key
+ .long sys_request_key
+ .long sys_keyctl
+ .long sys_ioprio_set
+ .long sys_ioprio_get /* 290 */
+ .long sys_inotify_init
+ .long sys_inotify_add_watch
+ .long sys_inotify_rm_watch
+ .long sys_ni_syscall /* sys_migrate_pages */
+ .long sys_ni_syscall /* 295 */ /* sys_openat */
+ .long sys_ni_syscall /* sys_mkdirat */
+ .long sys_ni_syscall /* sys_mknodat */
+ .long sys_ni_syscall /* sys_fchownat */
+ .long sys_ni_syscall /* sys_futimesat */
+ .long sys_ni_syscall /* 300 */ /* sys_fstatat64 */
+ .long sys_ni_syscall /* sys_unlinkat */
+ .long sys_ni_syscall /* sys_renameat */
+ .long sys_ni_syscall /* sys_linkat */
+ .long sys_ni_syscall /* sys_symlinkat */
+ .long sys_ni_syscall /* 305 */ /* sys_readlinkat */
+ .long sys_ni_syscall /* sys_fchmodat */
+ .long sys_ni_syscall /* sys_faccessat */
+ .long sys_ni_syscall /* pselect6 */
+ .long sys_ni_syscall /* ppoll */
+ .long sys_ni_syscall /* 310 */ /* sys_unshare */
+ .long sys_ni_syscall /* sys_set_robust_list */
+ .long sys_ni_syscall /* sys_get_robust_list */
+ .long sys_ni_syscall /* sys_splice */
+ .long sys_ni_syscall /* sys_sync_file_range */
+ .long sys_ni_syscall /* 315 */ /* sys_tee */
+ .long sys_ni_syscall /* sys_vmsplice */
+ .long sys_move_pages
+ .long sys_getcpu
+ .long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd
+ .long sys_eventfd
+ .long sys_fallocate
+
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..8940f1f
--- /dev/null
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -0,0 +1,145 @@
+/*
+ * arch/microblaze/kernel/vmlinux.lds.S
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+#include <linux/autoconf.h>
+#include <asm-generic/vmlinux.lds.h>
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+ . = CONFIG_KERNEL_BASE_ADDR;
+
+ .text : {
+ _text = . ;
+ _stext = . ;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ . = ALIGN (4) ;
+ _etext = . ;
+ }
+
+ . = ALIGN(16);
+ RODATA
+
+ /* sdata2 section can go anywhere, but must be word aligned
+ and SDA2_BASE must point to the middle of it */
+ .sdata2 : {
+ _ssrw = .;
+ . = ALIGN(0x8);
+ *(.sdata2)
+ . = ALIGN(8);
+ _essrw = .;
+ _ssrw_size = _essrw - _ssrw;
+ _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+ }
+
+ _sdata = . ;
+ .data ALIGN (0x4) : {
+ DATA_DATA
+ }
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ _edata = . ;
+
+ /* The initial task */
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+ . = ALIGN(8);
+ .sdata : {
+ _ssro = .;
+ *(.sdata)
+ }
+
+ .sbss : {
+ _ssbss = .;
+ *(.sbss)
+ _esbss = .;
+ _essro = .;
+ _ssro_size = _essro - _ssro ;
+ _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
+ }
+
+ . = ALIGN(16);
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ __init_begin = .;
+
+ . = ALIGN(4096);
+ .init.text : {
+ _sinittext = . ;
+ *(.init.text)
+ *(.exit.text)
+ *(.exit.data)
+ _einittext = .;
+ }
+
+ .init.data : { *(.init.data) }
+
+ . = ALIGN(4);
+ .init.ivt : {
+ __ivt_start = .;
+ *(.init.ivt)
+ __ivt_end = .;
+ }
+
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ .initcall.init : {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ __init_end_before_initramfs = .;
+
+ .init.ramfs ALIGN(4096) : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ . = ALIGN(4);
+ LONG(0);
+ . = ALIGN(4096);/* Pad init.ramfs up to page boundary, so
+ that __init_end == __bss_start. This will
+ make image.elf consistent with the image.bin */
+ }
+
+ __init_end = .;
+
+ .bss ALIGN (4096) : {
+ __bss_start = . ;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN (4) ;
+ __bss_stop = . ;
+ _ebss = . ;
+ }
+ . = ALIGN(4096);
+ _end = .;
+}
+
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 16/52] [microblaze] supported function for memory - kernel/lib
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (5 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 15/52] [microblaze] assembler files head.S, entry.S, monstr
@ 2008-01-24 15:02 ` monstr
2008-01-29 21:26 ` Jan Engelhardt
2008-01-24 15:02 ` [PATCH 17/52] [microblaze] checksum support monstr
` (44 subsequent siblings)
51 siblings, 1 reply; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/lib/memcpy.c | 159 +++++++++++++++++++++++++++++++++++++
arch/microblaze/lib/memmove.c | 174 +++++++++++++++++++++++++++++++++++++++++
arch/microblaze/lib/memset.c | 83 +++++++++++++++++++
3 files changed, 416 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/lib/memcpy.c
create mode 100644 arch/microblaze/lib/memmove.c
create mode 100644 arch/microblaze/lib/memset.c
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
new file mode 100644
index 0000000..cc13ebd
--- /dev/null
+++ b/arch/microblaze/lib/memcpy.c
@@ -0,0 +1,159 @@
+/* Filename: memcpy.c
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+#include <asm/system.h>
+
+/* Macro's for bytebliting unaligned data blocks */
+
+/* Big-endian MACROS */
+
+#define BYTE_BLIT_INIT(s, h, o) \
+ (h) = *((unsigned *)(s))++ << (o)
+
+#define BYTE_BLIT_STEP(d, s, h, o) \
+ { register unsigned _v_; _v_ = *((unsigned *)(s))++; \
+ *((unsigned *)(d))++ = (h) | _v_ >> (32-(o)); \
+ (h) = _v_ << (o); \
+ }
+
+void *memcpy(void *d, const void *s, __kernel_size_t c)
+{
+#if 1
+ /* This code was put into place as we transitioned from gcc3 to gcc4.
+ * gcc4 does not support the syntax *((char *)d)++ which causes the
+ * original code below to break. Short of fixing up the original code,
+ * a simpler byte oriented code was put into place.
+ */
+ /* Simple, byte oriented memcpy. */
+ const char *src = s;
+ char *dst = d;
+
+ while (c--) *dst++ = *src++;
+
+ return d;
+
+#else
+ /* The following code tries to optimize the copy by using unsigned
+ * alignment. This will work fine if both source and destination are
+ * aligned on the same boundary. However, if they are aligned on
+ * different boundaries shifts will be necessary. This might result in
+ * bad performance on MicroBlaze systems without a barrel shifter.
+ */
+ void *r = d;
+
+ if (c >= 4) {
+ unsigned x, a, h, align;
+
+ /* Align the destination to a word boundry. */
+ /* This is done in an endian independant manner. */
+ switch ((unsigned) d & 3) {
+ case 1:
+ *((char *) d)++ = *((char *) s)++;
+ c--;
+ case 2:
+ *((char *) d)++ = *((char *) s)++;
+ c--;
+ case 3:
+ *((char *) d)++ = *((char *) s)++;
+ c--;
+ }
+ /* Choose a copy scheme based on the source */
+ /* alignment relative to destination. */
+ switch ((unsigned) s & 3) {
+ case 0x0: /* Both byte offsets are aligned */
+
+ for (; c >= 4; c -= 4)
+ *((unsigned *) d)++ = *((unsigned *) s)++;
+
+ break;
+
+ case 0x1: /* Unaligned - Off by 1 */
+ /* Word align the source */
+ a = (unsigned) s & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 8);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 8);
+
+ /* Realign the source */
+ (unsigned) s = a - 3;
+ break;
+
+ case 0x2: /* Unaligned - Off by 2 */
+ /* Word align the source */
+ a = (unsigned) s & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 16);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 16);
+
+ /* Realign the source */
+ (unsigned) s = a - 2;
+ break;
+
+ case 0x3: /* Unaligned - Off by 3 */
+ /* Word align the source */
+ a = (unsigned) s & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 24);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 24);
+
+ /* Realign the source */
+ (unsigned) s = a - 1;
+ break;
+ }
+
+ }
+
+ /* Finish off any remaining bytes */
+ /* simple fast copy, ... unless a cache boundry is crossed */
+ switch (c) {
+ case 3:
+ *((char *) d)++ = *((char *) s)++;
+ case 2:
+ *((char *) d)++ = *((char *) s)++;
+ case 1:
+ *((char *) d)++ = *((char *) s)++;
+ }
+
+ return r;
+#endif
+}
+
+
+void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c)
+{
+ return memcpy(d, s, c);
+}
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
new file mode 100644
index 0000000..e9f8f04
--- /dev/null
+++ b/arch/microblaze/lib/memmove.c
@@ -0,0 +1,174 @@
+/* Filename: memmove.c
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memmove.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+
+/* Macro's for bytebliting unaligned data blocks */
+
+/* Big-endian MACROS */
+
+#define BYTE_BLIT_INIT(s, h, o) \
+ (h) = *(--(unsigned *)(s)) >> (32-(o))
+
+#define BYTE_BLIT_STEP(d, s, h, o) \
+ { register unsigned _v_; _v_ = *(--(unsigned *)(s)); \
+ *(--(unsigned *)(d)) = _v_ << (o) | (h); \
+ (h) = _v_ >> (32-(o)); \
+ }
+
+void *memmove(void *d, const void *s, __kernel_size_t c)
+{
+#if 1
+ /* This code was put into place as we transitioned from gcc3 to gcc4.
+ * gcc4 does not support the syntax *((char *)d)++ which causes the
+ * original code below to break. Short of fixing up the original code,
+ * a simpler byte oriented code was put into place.
+ */
+ /* Simple, byte oriented memmove. */
+ if (d <= s) {
+ return memcpy(d, s, c);
+ } else {
+ const char *src = s;
+ char *dst = d;
+
+ /* copy backwards, from end to beginning */
+ src += c;
+ dst += c;
+
+ while (c--) *--dst = *--src;
+
+ return d;
+ }
+
+#else
+ /* The following code tries to optimize the copy by using unsigned
+ * alignment. This will work fine if both source and destination are
+ * aligned on the same boundary. However, if they are aligned on
+ * different boundaries shifts will be necessary. This might result in
+ * bad performance on MicroBlaze systems without a barrel shifter.
+ */
+ void *r = d;
+
+ /* Use memcpy when source is higher than dest */
+ if (d <= s)
+ return memcpy(d, s, c);
+
+ /* Do a descending copy - this is a bit trickier! */
+ d += c;
+ s += c;
+
+ if (c >= 4) {
+ unsigned x, a, h, align;
+
+ /* Align the destination to a word boundry. */
+ /* This is done in an endian independant manner. */
+ switch ((unsigned) d & 3) {
+ case 3:
+ *(--(char *) d) = *(--(char *) s);
+ c--;
+ case 2:
+ *(--(char *) d) = *(--(char *) s);
+ c--;
+ case 1:
+ *(--(char *) d) = *(--(char *) s);
+ c--;
+ }
+ /* Choose a copy scheme based on the source */
+ /* alignment relative to destination. */
+ switch ((unsigned) s & 3) {
+ case 0x0: /* Both byte offsets are aligned */
+
+ for (; c >= 4; c -= 4)
+ *(--(unsigned *) d) = *(--(unsigned *) s);
+
+ break;
+
+ case 0x1: /* Unaligned - Off by 1 */
+ /* Word align the source */
+ a = (unsigned) (s + 4) & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 8);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 8);
+
+ /* Realign the source */
+ (unsigned) s = a + 1;
+ break;
+
+ case 0x2: /* Unaligned - Off by 2 */
+ /* Word align the source */
+ a = (unsigned) (s + 4) & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 16);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 16);
+
+ /* Realign the source */
+ (unsigned) s = a + 2;
+ break;
+
+ case 0x3: /* Unaligned - Off by 3 */
+ /* Word align the source */
+ a = (unsigned) (s + 4) & ~3;
+
+ /* Load the holding buffer */
+ BYTE_BLIT_INIT(a, h, 24);
+
+ for (; c >= 4; c -= 4)
+ BYTE_BLIT_STEP(d, a, h, 24);
+
+ /* Realign the source */
+ (unsigned) s = a + 3;
+ break;
+ }
+
+#if 0
+ /* Finish off any remaining bytes */
+ c &= 3;
+ goto finish;
+#endif
+
+ }
+
+ /* simple fast copy, ... unless a cache boundry is crossed */
+ switch (c) {
+ case 4:
+ *(--(char *) d) = *(--(char *) s);
+ case 3:
+ *(--(char *) d) = *(--(char *) s);
+ case 2:
+ *(--(char *) d) = *(--(char *) s);
+ case 1:
+ *(--(char *) d) = *(--(char *) s);
+ }
+ return r;
+#endif
+}
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
new file mode 100644
index 0000000..5d3d83e
--- /dev/null
+++ b/arch/microblaze/lib/memset.c
@@ -0,0 +1,83 @@
+/* Filename: memset.c
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+/* Filename: memcpy.c
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * Based on demo code originally Copyright 2001 by Intel Corp.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+
+#include <asm/string.h>
+
+void *memset(void *s, int c, __kernel_size_t n)
+{
+ void *r = s;
+ unsigned int w32;
+
+ /* Truncate c to 8 bits */
+ w32 = c = (c & 0xFF);
+
+ /* Make a repeating word out of it */
+ w32 |= w32 << 8;
+ w32 |= w32 << 8;
+ w32 |= w32 << 8;
+
+ if (n >= 4) {
+ /* Align the destination to a word boundary. */
+ /* This is done in an endian independant manner. */
+ switch ((unsigned) s & 3) {
+ case 1: *(char *)s = c; s = (char *)s+1; n--;
+ case 2: *(char *)s = c; s = (char *)s+1; n--;
+ case 3: *(char *)s = c; s = (char *)s+1; n--;
+ }
+
+ /* Do as many full-word copies as we can */
+ for (; n >= 4; n -= 4) {
+ *(unsigned *)s = w32;
+ s = (unsigned *)s + 1;
+ }
+
+ }
+
+ /* Finish off the rest as byte sets */
+ while (n--) {
+ *(char *)s = c;
+ s = (char *)s+1;
+ }
+ return r;
+}
+
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 16/52] [microblaze] supported function for memory - kernel/lib
2008-01-24 15:02 ` [PATCH 16/52] [microblaze] supported function for memory - kernel/lib monstr
@ 2008-01-29 21:26 ` Jan Engelhardt
0 siblings, 0 replies; 67+ messages in thread
From: Jan Engelhardt @ 2008-01-29 21:26 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Jan 24 2008 16:02, monstr@monstr.eu wrote:
>diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
>new file mode 100644
>index 0000000..cc13ebd
>--- /dev/null
>+++ b/arch/microblaze/lib/memcpy.c
>@@ -0,0 +1,159 @@
>+/* Filename: memcpy.c
>+ *
Please, no such filenames in files. It is redundant and hard to keep
uptodate, should things move at one point in time.
>+#define BYTE_BLIT_STEP(d, s, h, o) \
>+ { register unsigned _v_; _v_ = *((unsigned *)(s))++; \
>+ *((unsigned *)(d))++ = (h) | _v_ >> (32-(o)); \
>+ (h) = _v_ << (o); \
>+ }
'register' is a relict from 30 years ago. Compilers likely ignore it
these days, so it can jsut be removed anyway.
>+ /* This code was put into place as we transitioned from gcc3 to gcc4.
>+ * gcc4 does not support the syntax *((char *)d)++ which causes the
Of course not, because (char *)d is not an lvalue - and if you ask
me, it is ambiguous and bogus code.
Assuming 'd' was int*, d++ would cause it to be incremented by 4.
If you incremented 'd' with char* semantics, it would be incremented
by 1. But since 'd' is still int*, you now have an unaligned pointer,
which is a problem in itself. We do not need more pitfalls than C
already provides.
>+ if (c >= 4) {
>+ unsigned x, a, h, align;
You will be wanting to use unsigned long since you are working with
pointers.
>+ /* Align the destination to a word boundry. */
>+ /* This is done in an endian independant manner. */
>+ switch ((unsigned) d & 3) {
>+ case 1:
>+ *((char *) d)++ = *((char *) s)++;
>+ c--;
>+ case 2:
>+ *((char *) d)++ = *((char *) s)++;
>+ c--;
>+ case 3:
>+ *((char *) d)++ = *((char *) s)++;
>+ c--;
>+ }
This gets my strongest NAK. Please rewrite it in a sane manner.
In other words, like this:
+void *memcpy(void *v_dest, const void *v_src, __kernel_size_t c)
+{
+ const char *src = v_src;
+ char *dest = v_dest;
+
+ const uint32_t *i_src;
+ uint32_t *i_dest;
+
+ if (c >= 4) {
+ unsigned x, a, h, align;
+
+ /* Align the destination to a word boundry. */
+ /* This is done in an endian independant manner. */
+ switch ((unsigned long)dest & 3) {
+ case 1:
+ *dest++ = *src++;
+ --c;
+ case 2:
+ *dest++ = *src++;
+ --c;
+ case 3:
+ *dest++ = *src++;
+ --c;
+ }
+ /* Choose a copy scheme based on the source */
+ /* alignment relative to destination. */
+ switch ((unsigned long)src & 3) {
+ case 0x0: /* Both byte offsets are aligned */
+
+ i_src = (const void *)src;
+ i_dest = (void *)dest;
+
+ for (; c >= 4; c -= 4)
+ *i_dest++ = *i_src++;
+
+ src = (const void *)i_src;
+ dest = (void *)i_dest;
+
+ break;
+
+ case 0x1: /* Unaligned - Off by 1 */
...
The BYTE_BLIT_ macros need reworking. The suggestions
so far should provide everything needed.
+ }
+
+ }
+
+ /* Finish off any remaining bytes */
+ /* simple fast copy, ... unless a cache boundry is crossed */
+ switch (c) {
+ case 3:
+ *dest++ = *src++;
+ case 2:
+ *dest++ = *src++;
+ case 1:
+ *dest++ = *src++;
+ }
+
+ return r;
+#endif
+}
- and voilà, you can use it even with gcc4.
The same goes for memmove.c and memset.c.
By the way, I think you should just replace lib/string.c's memcpy,
etc. (which still do per-byte copying) with this optimized variant
instead, so everyone can benefit.
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 17/52] [microblaze] checksum support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (6 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 16/52] [microblaze] supported function for memory - kernel/lib monstr
@ 2008-01-24 15:02 ` monstr
2008-01-27 11:57 ` Geert Uytterhoeven
2008-01-29 21:30 ` Jan Engelhardt
2008-01-24 15:02 ` [PATCH 18/52] [microblaze] early_printk support monstr
` (43 subsequent siblings)
51 siblings, 2 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/lib/checksum.c | 159 +++++++++++++++++++++++++++++++++++++
include/asm-microblaze/checksum.h | 101 +++++++++++++++++++++++
2 files changed, 260 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/lib/checksum.c
create mode 100644 include/asm-microblaze/checksum.h
diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
new file mode 100644
index 0000000..21a6830
--- /dev/null
+++ b/arch/microblaze/lib/checksum.c
@@ -0,0 +1,159 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * IP/TCP/UDP checksumming routines
+ *
+ * Authors: Jorge Cwik, <jorge@laser.satlink.net>
+ * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ * Tom May, <ftom@netcom.com>
+ * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ * Lots of code moved from tcp.c and ip.c; see those files
+ * for more names.
+ *
+ * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
+ * Fixed some nasty bugs, causing some horrible crashes.
+ * A: At some points, the sum (%0) was used as
+ * length-counter instead of the length counter
+ * (%1). Thanks to Roman Hodek for pointing this out.
+ * B: GCC seems to mess up if one uses too many
+ * data-registers to hold input values and one tries to
+ * specify d0 and d1 as scratch registers. Letting gcc choose these
+ * registers itself solves the problem.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
+ kills, so most of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+ /* add up 16-bit and 16-bit for 16+c bit */
+ x = (x & 0xffff) + (x >> 16);
+ /* add up carry.. */
+ x = (x & 0xffff) + (x >> 16);
+ return x;
+}
+
+static unsigned long do_csum(const unsigned char *buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = *buff;
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(unsigned short *) buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+ unsigned long carry = 0;
+ do {
+ unsigned long w = *(unsigned long *) buff;
+ count--;
+ buff += 4;
+ result += carry;
+ result += w;
+ carry = (w > result);
+ } while (count);
+ result += carry;
+ result = (result & 0xffff) + (result >> 16);
+ }
+ if (len & 2) {
+ result += *(unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += (*buff << 8);
+ result = from32to16(result);
+ if (odd)
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+ return result;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+ return ~do_csum(iph, ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+ unsigned int result = do_csum(buff, len);
+
+ /* add in old sum, and carry.. */
+ result += sum;
+ if (sum > result)
+ result += 1;
+ return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char *buff, int len)
+{
+ return ~do_csum(buff, len);
+}
+
+ /*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum,
+ int *csum_err)
+{
+ if (csum_err)
+ *csum_err = 0;
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
diff --git a/include/asm-microblaze/checksum.h b/include/asm-microblaze/checksum.h
new file mode 100644
index 0000000..4b37bb5
--- /dev/null
+++ b/include/asm-microblaze/checksum.h
@@ -0,0 +1,101 @@
+/*
+ * include/asm-microblaze/checksum.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len,
+ unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+ int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum) \
+ csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ *
+ */
+extern unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+/*
+ * Fold a partial checksum
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = (sum & 0xffff) + (sum >> 16);
+ return ~sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+ unsigned short proto, unsigned int sum)
+{
+ __asm__("add %0, %4, %1\n\t"
+ "addc %0, %4, %2\n\t"
+ "addc %0, %4, %3\n\t"
+ "addc %0, %4, r0\n\t"
+ : "=d" (sum)
+ : "d" (saddr), "d" (daddr), "d" (len + proto),
+ "0"(sum));
+
+ return sum;
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+ unsigned short proto, unsigned int sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+extern unsigned short ip_compute_csum(const unsigned char *buff, int len);
+
+#endif /* _ASM_CHECKSUM_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 17/52] [microblaze] checksum support
2008-01-24 15:02 ` [PATCH 17/52] [microblaze] checksum support monstr
@ 2008-01-27 11:57 ` Geert Uytterhoeven
2008-01-27 13:41 ` Michal Simek
2008-01-29 21:30 ` Jan Engelhardt
1 sibling, 1 reply; 67+ messages in thread
From: Geert Uytterhoeven @ 2008-01-27 11:57 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Thu, 24 Jan 2008, monstr@monstr.eu wrote:
> From: Michal Simek <monstr@monstr.eu>
>
>
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> ---
> arch/microblaze/lib/checksum.c | 159 +++++++++++++++++++++++++++++++++++++
> include/asm-microblaze/checksum.h | 101 +++++++++++++++++++++++
> 2 files changed, 260 insertions(+), 0 deletions(-)
> create mode 100644 arch/microblaze/lib/checksum.c
> create mode 100644 include/asm-microblaze/checksum.h
>
> diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
> new file mode 100644
> index 0000000..21a6830
> --- /dev/null
> +++ b/arch/microblaze/lib/checksum.c
> @@ -0,0 +1,159 @@
> +/*
> + * INET An implementation of the TCP/IP protocol suite for the LINUX
> + * operating system. INET is implemented using the BSD Socket
> + * interface as the means of communication with the user level.
> + *
> + * IP/TCP/UDP checksumming routines
> + *
> + * Authors: Jorge Cwik, <jorge@laser.satlink.net>
> + * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
> + * Tom May, <ftom@netcom.com>
> + * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
> + * Lots of code moved from tcp.c and ip.c; see those files
> + * for more names.
> + *
> + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
> + * Fixed some nasty bugs, causing some horrible crashes.
> + * A: At some points, the sum (%0) was used as
> + * length-counter instead of the length counter
> + * (%1). Thanks to Roman Hodek for pointing this out.
> + * B: GCC seems to mess up if one uses too many
> + * data-registers to hold input values and one tries to
> + * specify d0 and d1 as scratch registers. Letting gcc choose these
> + * registers itself solves the problem.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
> + kills, so most of the assembly has to go. */
So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
checkpatch.pl fixes but without the sparse fixes?
Furthermore, it's just plain C, so maybe we need a common one that can
be shared by multiple archs?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [PATCH 17/52] [microblaze] checksum support
2008-01-27 11:57 ` Geert Uytterhoeven
@ 2008-01-27 13:41 ` Michal Simek
2008-01-27 15:12 ` Geert Uytterhoeven
0 siblings, 1 reply; 67+ messages in thread
From: Michal Simek @ 2008-01-27 13:41 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
Hi Geert,
> So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
> checkpatch.pl fixes but without the sparse fixes?
> Furthermore, it's just plain C, so maybe we need a common one that can
> be shared by multiple archs?
>
> Gr{oetje,eeting}s,
> Geert
>
I have no sparse errors and warning in checksum.c file.
Michal Simek
www.monstr.eu
^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [PATCH 17/52] [microblaze] checksum support
2008-01-27 13:41 ` Michal Simek
@ 2008-01-27 15:12 ` Geert Uytterhoeven
0 siblings, 0 replies; 67+ messages in thread
From: Geert Uytterhoeven @ 2008-01-27 15:12 UTC (permalink / raw)
To: Michal Simek
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Sun, 27 Jan 2008, Michal Simek wrote:
> > So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
> > checkpatch.pl fixes but without the sparse fixes?
> > Furthermore, it's just plain C, so maybe we need a common one that can
> > be shared by multiple archs?
> >
>
> I have no sparse errors and warning in checksum.c file.
How come csum_partial_copy_from_user() in arch/m68knommu/lib/checksum.c
has a __user attribute on the src parameter, while yours doesn't?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [PATCH 17/52] [microblaze] checksum support
2008-01-24 15:02 ` [PATCH 17/52] [microblaze] checksum support monstr
2008-01-27 11:57 ` Geert Uytterhoeven
@ 2008-01-29 21:30 ` Jan Engelhardt
1 sibling, 0 replies; 67+ messages in thread
From: Jan Engelhardt @ 2008-01-29 21:30 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
On Jan 24 2008 16:02, monstr@monstr.eu wrote:
>+
>+ /*
>+ * copy from fs while checksumming, otherwise like csum_partial
>+ */
>+
That comment got messed up. Also, does any other CPU than x86
have a %ds and %fs register?
If it copies directly from user context, a __user annotation would be
helpful.
>+unsigned int
>+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum,
>+ int *csum_err)
>+{
>+ if (csum_err)
>+ *csum_err = 0;
>+ memcpy(dst, src, len);
>+ return csum_partial(dst, len, sum);
>+}
>+
>+/*
>+ * copy from ds while checksumming, otherwise like csum_partial
>+ */
Ditto.
>+
>+unsigned int
>+csum_partial_copy(const char *src, char *dst, int len, int sum)
>+{
>+ memcpy(dst, src, len);
>+ return csum_partial(dst, len, sum);
>+}
>diff --git a/include/asm-microblaze/checksum.h b/include/asm-microblaze/checksum.h
>new file mode 100644
>index 0000000..4b37bb5
>--- /dev/null
>+++ b/include/asm-microblaze/checksum.h
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 18/52] [microblaze] early_printk support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (7 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 17/52] [microblaze] checksum support monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 19/52] [microblaze] uaccess files monstr
` (42 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/early_printk.c | 115 +++++++++++++++++++++++++++++++++
1 files changed, 115 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/early_printk.c
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
new file mode 100644
index 0000000..0f533ff
--- /dev/null
+++ b/arch/microblaze/kernel/early_printk.c
@@ -0,0 +1,115 @@
+/*
+ * arch/microblaze/kernel/early_printk.c
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ * Early printk support for Microblaze.
+ *
+ * Once we got some system without uart light, we need to refactor.
+ */
+
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/fcntl.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_EARLY_PRINTK
+#define BASE_ADDR ((unsigned char *)CONFIG_EARLY_PRINTK_UARTLITE_ADDRESS)
+
+#define RX_FIFO BASE_ADDR
+#define TX_FIFO ((unsigned long *)(BASE_ADDR + 4))
+#define STATUS ((unsigned long *)(BASE_ADDR + 8))
+#define CONTROL ((unsigned long *)(BASE_ADDR + 12))
+
+static void early_printk_putc(char c)
+{
+ while (ioread32(STATUS) & (1<<3));
+ iowrite32((c & 0xff), TX_FIFO);
+}
+
+static void early_printk_write(struct console *unused,
+ const char *s, unsigned n)
+{
+ while (*s && n-- > 0) {
+ early_printk_putc(*s);
+ if (*s == '\n')
+ early_printk_putc('\r');
+ s++;
+ }
+}
+
+static struct console early_serial_console = {
+ .name = "earlyser",
+ .write = early_printk_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+/* Direct interface for emergencies */
+static struct console *early_console = &early_serial_console;
+static int early_console_initialized;
+
+void early_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ if (early_console_initialized) {
+ va_start(ap, fmt);
+ n = vscnprintf(buf, 512, fmt, ap);
+ early_console->write(early_console, buf, n);
+ va_end(ap);
+ }
+}
+
+static int __initdata keep_early;
+
+int __init setup_early_printk(char *opt)
+{
+ char *space;
+ char buf[256];
+
+ if (early_console_initialized)
+ return 1;
+
+ strlcpy(buf, opt, sizeof(buf));
+ space = strchr(buf, ' ');
+ if (space)
+ *space = 0;
+
+ if (strstr(buf, "keep"))
+ keep_early = 1;
+
+ early_console = &early_serial_console;
+ early_console_initialized = 1;
+ register_console(early_console);
+ return 0;
+}
+#if 0
+static void __init disable_early_printk(void)
+{
+ if (!early_console_initialized || !early_console)
+ return;
+ if (!keep_early) {
+ printk(KERN_INFO "disabling early console\n");
+ unregister_console(early_console);
+ early_console_initialized = 0;
+ } else
+ printk(KERN_INFO "keeping early console\n");
+}
+#endif
+
+__setup("earlyprintk=", setup_early_printk);
+
+#else
+void early_printk(const char *fmt, ...)
+{
+}
+#endif
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 19/52] [microblaze] uaccess files
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (8 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 18/52] [microblaze] early_printk support monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 20/52] [microblaze] heartbeat file monstr
` (41 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/lib/uaccess.c | 43 +++++++++++++
include/asm-microblaze/uaccess.h | 126 ++++++++++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/lib/uaccess.c
create mode 100644 include/asm-microblaze/uaccess.h
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c
new file mode 100644
index 0000000..be201a0
--- /dev/null
+++ b/arch/microblaze/lib/uaccess.c
@@ -0,0 +1,43 @@
+/*
+ * arch/microblaze/lib/uaccess.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/string.h>
+#include <asm/uaccess.h>
+
+#include <asm/bug.h>
+
+long strnlen_user(const char *s, long n)
+{
+ return strlen(s) + 1;
+}
+
+#define __do_strncpy_from_user(dst, src, count, res) \
+ do { \
+ char *tmp; \
+ strncpy(dst, src, count); \
+ for (tmp = dst; *tmp && count > 0; tmp++, count--) \
+ ; \
+ res = (tmp - dst); \
+ } while (0)
+
+long __strncpy_from_user(char *dst, const char *src, long count)
+{
+ long res;
+ __do_strncpy_from_user(dst, src, count, res);
+ return res;
+}
+
+long strncpy_from_user(char *dst, const char *src, long count)
+{
+ long res = -EFAULT;
+ if (access_ok(VERIFY_READ, src, 1))
+ __do_strncpy_from_user(dst, src, count, res);
+ return res;
+}
diff --git a/include/asm-microblaze/uaccess.h b/include/asm-microblaze/uaccess.h
new file mode 100644
index 0000000..1ee4c63
--- /dev/null
+++ b/include/asm-microblaze/uaccess.h
@@ -0,0 +1,126 @@
+/*
+ * include/asm-microblaze/uaccess.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <asm/segment.h>
+#include <asm/string.h>
+
+#include <linux/sched.h> /* RLIMIT_FSIZE */
+/* #include <linux/errno.h> */
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+extern int ___range_ok(unsigned long addr, unsigned long size);
+
+#define __range_ok(addr, size) \
+ ___range_ok((unsigned long)(addr), (unsigned long)(size))
+
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
+
+extern inline int bad_user_access_length(void)
+{
+ return 0;
+}
+
+#define __get_user(var, ptr) \
+ ({ \
+ int __gu_err = 0; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ case 2: \
+ case 4: \
+ (var) = *(ptr); \
+ break; \
+ case 8: \
+ memcpy((void *) &(var), (ptr), 8); \
+ break; \
+ default: \
+ (var) = 0; \
+ __gu_err = __get_user_bad(); \
+ break; \
+ } \
+ __gu_err; \
+ })
+
+#define __get_user_bad() (bad_user_access_length (), (-EFAULT))
+
+#define __put_user(var, ptr) \
+ ({ \
+ int __pu_err = 0; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ case 2: \
+ case 4: \
+ *(ptr) = (var); \
+ break; \
+ case 8: { \
+ typeof(*(ptr)) __pu_val = var; \
+ memcpy(ptr, &__pu_val, sizeof(__pu_val));\
+ } \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+ })
+
+#define __put_user_bad() (bad_user_access_length (), (-EFAULT))
+
+#define put_user(x, ptr) __put_user(x, ptr)
+#define get_user(x, ptr) __get_user(x, ptr)
+
+#define copy_to_user(to, from, n) (memcpy(to, from, n), 0)
+#define copy_from_user(to, from, n) (memcpy(to, from, n), 0)
+
+#define __copy_to_user(to, from, n) (copy_to_user(to, from, n))
+#define __copy_from_user(to, from, n) (copy_from_user(to, from, n))
+#define __copy_to_user_inatomic(to, from, n) (__copy_to_user(to, from, n))
+#define __copy_from_user_inatomic(to, from, n) (__copy_from_user(to, from, n))
+
+#define __clear_user(addr, n) (memset((void *)addr, 0, n), 0)
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry {
+ unsigned long insn, fixup;
+};
+
+static inline unsigned long clear_user(void *addr, unsigned long size)
+{
+ if (access_ok(VERIFY_WRITE, addr, size))
+ size = __clear_user(addr, size);
+ return size;
+}
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+extern long strncpy_from_user(char *dst, const char *src, long count);
+extern long strnlen_user(const char *src, long count);
+extern long __strncpy_from_user(char *dst, const char *src, long count);
+
+#endif /* _ASM_UACCESS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 20/52] [microblaze] heartbeat file
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (9 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 19/52] [microblaze] uaccess files monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 21/52] [microblaze] setup.c - system setting monstr
` (40 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/heartbeat.c | 40 ++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/heartbeat.c
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
new file mode 100644
index 0000000..e29aa1f
--- /dev/null
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -0,0 +1,40 @@
+/*
+ * arch/microblaze/kernel/heartbeat.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/sched.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+void heartbeat(void)
+{
+#if 0
+ static unsigned int cnt, period, dist;
+
+ if (cnt == 0 || cnt == dist) {
+ iowrite32(1, CONFIG_XILINX_LEDS_4BIT_BASEADDR);
+ } else if (cnt == 7 || cnt == dist + 7) {
+ iowrite32(0, CONFIG_XILINX_LEDS_4BIT_BASEADDR);
+ }
+
+ if (++cnt > period) {
+ cnt = 0;
+
+ /*
+ * The hyperbolic function below modifies the heartbeat period
+ * length in dependency of the current (5min) load. It goes
+ * through the points f(0)=126, f(1)=86, f(5)=51, f(inf)->30.
+ */
+ period = ((672 << FSHIFT) / (5 * avenrun[0] +
+ (7 << FSHIFT))) + 30;
+ dist = period / 4;
+ }
+#endif
+}
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 21/52] [microblaze] setup.c - system setting
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (10 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 20/52] [microblaze] heartbeat file monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 22/52] [microblaze] asm-offsets monstr
` (39 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/setup.c | 170 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 170 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/setup.c
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
new file mode 100644
index 0000000..1d05fac
--- /dev/null
+++ b/arch/microblaze/kernel/setup.c
@@ -0,0 +1,170 @@
+/*
+ * arch/microblaze/kernel/setup.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/bug.h>
+#include <asm/param.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/entry.h>
+#include <asm/cpuinfo.h>
+
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+
+DEFINE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DEFINE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+
+char command_line[COMMAND_LINE_SIZE];
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+
+void __init setup_arch(char **cmdline_p)
+{
+ console_verbose();
+
+ unflatten_device_tree();
+ /* NOTE I think that this function is not necessary to call */
+ /* irq_early_init(); */
+ setup_cpuinfo();
+
+ __flush_icache_all();
+ __enable_icache();
+
+ __flush_dcache_all();
+ __enable_dcache();
+
+ panic_timeout = 120;
+
+ setup_memory();
+ paging_init();
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_XILINX_CONSOLE)
+ conswitchp = &xil_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+#ifdef CONFIG_MTD_UCLINUX_EBSS
+/* Handle both romfs and cramfs types, without generating unnecessary
+ code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+ if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */
+ return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+ if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */
+ return le32_to_cpu(addr[1]);
+#endif
+ return 0;
+}
+#endif /* CONFIG_MTD_UCLINUX_EBSS */
+
+void __init machine_early_init(const char *cmdline, unsigned int ram,
+ unsigned int fdt)
+{
+ unsigned long *src, *dst = (unsigned long *)0x0;
+ early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt);
+
+#ifdef CONFIG_MTD_UCLINUX_EBSS
+ {
+ int size;
+ unsigned int romfs_base;
+ romfs_base = (ram ? ram : (unsigned int)&__init_end);
+ /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the
+ * end of kernel, which is ROMFS_LOCATION defined above. */
+ size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
+ early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+ romfs_base, size);
+ early_printk("#### klimit %p ####\n", klimit);
+ BUG_ON(size < 0); /* What else can we do? */
+
+ /* Use memmove to handle likely case of memory overlap */
+ early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n",
+ size, romfs_base, &_ebss);
+ memmove(&_ebss, (int *)romfs_base, size);
+
+ /* update klimit */
+ klimit += PAGE_ALIGN(size);
+ early_printk("New klimit: 0x%08x\n", klimit);
+ }
+#endif
+
+ memset(__bss_start, 0, __bss_stop-__bss_start);
+ memset(_ssbss, 0, _esbss-_ssbss);
+
+ printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt);
+ early_init_devtree((void *)fdt);
+
+ /* Copy command line passed from bootloader, or use default
+ if none provided, or forced */
+#ifndef CONFIG_CMDLINE_FORCE
+ if (cmdline && cmdline[0] != '\0')
+ strlcpy(command_line, cmdline, COMMAND_LINE_SIZE);
+ else
+#endif
+ strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE);
+
+ for (src = __ivt_start; src < __ivt_end; src++, dst++)
+ *dst = *src;
+
+ /* Initialize global data */
+ per_cpu(KM, 0) = 0x1; /* We start in kernel mode */
+ per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
+
+}
+
+void machine_restart(char *cmd)
+{
+ printk(KERN_NOTICE "Machine restart...\n");
+ dump_stack();
+ while (1)
+ ;
+}
+
+void machine_shutdown(void)
+{
+ printk(KERN_NOTICE "Machine shutdown...\n");
+ while (1)
+ ;
+}
+
+void machine_halt(void)
+{
+ printk(KERN_NOTICE "Machine halt...\n");
+ while (1)
+ ;
+}
+
+void machine_power_off(void)
+{
+ printk(KERN_NOTICE "Machine power off...\n");
+ while (1)
+ ;
+}
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 22/52] [microblaze] asm-offsets
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (11 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 21/52] [microblaze] setup.c - system setting monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 23/52] [microblaze] process and init task function monstr
` (38 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/asm-offsets.c | 118 ++++++++++++++++++++++++++++++++++
1 files changed, 118 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/asm-offsets.c
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
new file mode 100644
index 0000000..f01aa3b
--- /dev/null
+++ b/arch/microblaze/kernel/asm-offsets.c
@@ -0,0 +1,118 @@
+/*
+ * arch/microblaze/kernel/asm-offset.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/thread_info.h>
+
+#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define BLANK() asm volatile("\n->" : :)
+
+int main(int argc, char *argv[])
+{
+ /* struct pt_regs */
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ DEFINE(PT_MSR, offsetof(struct pt_regs, msr));
+ DEFINE(PT_EAR, offsetof(struct pt_regs, ear));
+ DEFINE(PT_ESR, offsetof(struct pt_regs, esr));
+ DEFINE(PT_FSR, offsetof(struct pt_regs, fsr));
+ DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+ DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+ DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+ DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+ DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+ DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+ DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+ DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+ DEFINE(PT_R8, offsetof(struct pt_regs, r8));
+ DEFINE(PT_R9, offsetof(struct pt_regs, r9));
+ DEFINE(PT_R10, offsetof(struct pt_regs, r10));
+ DEFINE(PT_R11, offsetof(struct pt_regs, r11));
+ DEFINE(PT_R12, offsetof(struct pt_regs, r12));
+ DEFINE(PT_R13, offsetof(struct pt_regs, r13));
+ DEFINE(PT_R14, offsetof(struct pt_regs, r14));
+ DEFINE(PT_R15, offsetof(struct pt_regs, r15));
+ DEFINE(PT_R16, offsetof(struct pt_regs, r16));
+ DEFINE(PT_R17, offsetof(struct pt_regs, r17));
+ DEFINE(PT_R18, offsetof(struct pt_regs, r18));
+ DEFINE(PT_R19, offsetof(struct pt_regs, r19));
+ DEFINE(PT_R20, offsetof(struct pt_regs, r20));
+ DEFINE(PT_R21, offsetof(struct pt_regs, r21));
+ DEFINE(PT_R22, offsetof(struct pt_regs, r22));
+ DEFINE(PT_R23, offsetof(struct pt_regs, r23));
+ DEFINE(PT_R24, offsetof(struct pt_regs, r24));
+ DEFINE(PT_R25, offsetof(struct pt_regs, r25));
+ DEFINE(PT_R26, offsetof(struct pt_regs, r26));
+ DEFINE(PT_R27, offsetof(struct pt_regs, r27));
+ DEFINE(PT_R28, offsetof(struct pt_regs, r28));
+ DEFINE(PT_R29, offsetof(struct pt_regs, r29));
+ DEFINE(PT_R30, offsetof(struct pt_regs, r30));
+ DEFINE(PT_R31, offsetof(struct pt_regs, r31));
+ DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode));
+ BLANK();
+
+ /* Magic offsets for PTRACE PEEK/POKE etc */
+ DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1);
+ DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2);
+ DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3);
+ BLANK();
+
+ /* struct task_struct */
+ DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack));
+
+ /* struct thread_info */
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_STATUS, offsetof(struct thread_info, status));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block));
+ DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+ BLANK();
+
+ /* struct cpu_context */
+ DEFINE(CC_SP, offsetof(struct cpu_context, sp)); /* r1 */
+ DEFINE(CC_R2, offsetof(struct cpu_context, r2));
+ /* dedicated registers */
+ DEFINE(CC_R13, offsetof(struct cpu_context, r13));
+ DEFINE(CC_R14, offsetof(struct cpu_context, r14));
+ DEFINE(CC_R15, offsetof(struct cpu_context, r15));
+ DEFINE(CC_R16, offsetof(struct cpu_context, r16));
+ DEFINE(CC_R17, offsetof(struct cpu_context, r17));
+ DEFINE(CC_R18, offsetof(struct cpu_context, r18));
+ /* non-volatile registers */
+ DEFINE(CC_R19, offsetof(struct cpu_context, r19));
+ DEFINE(CC_R20, offsetof(struct cpu_context, r20));
+ DEFINE(CC_R21, offsetof(struct cpu_context, r21));
+ DEFINE(CC_R22, offsetof(struct cpu_context, r22));
+ DEFINE(CC_R23, offsetof(struct cpu_context, r23));
+ DEFINE(CC_R24, offsetof(struct cpu_context, r24));
+ DEFINE(CC_R25, offsetof(struct cpu_context, r25));
+ DEFINE(CC_R26, offsetof(struct cpu_context, r26));
+ DEFINE(CC_R27, offsetof(struct cpu_context, r27));
+ DEFINE(CC_R28, offsetof(struct cpu_context, r28));
+ DEFINE(CC_R29, offsetof(struct cpu_context, r29));
+ DEFINE(CC_R30, offsetof(struct cpu_context, r30));
+ /* special purpose registers */
+ DEFINE(CC_MSR, offsetof(struct cpu_context, msr));
+ DEFINE(CC_EAR, offsetof(struct cpu_context, ear));
+ DEFINE(CC_ESR, offsetof(struct cpu_context, esr));
+ DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
+ BLANK();
+
+ return 0;
+}
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 23/52] [microblaze] process and init task function
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (12 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 22/52] [microblaze] asm-offsets monstr
@ 2008-01-24 15:02 ` monstr
2008-01-24 15:02 ` [PATCH 24/52] [microblaze] time support monstr
` (37 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/init_task.c | 31 +++++++++
arch/microblaze/kernel/process.c | 129 ++++++++++++++++++++++++++++++++++++
2 files changed, 160 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/init_task.c
create mode 100644 arch/microblaze/kernel/process.c
diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c
new file mode 100644
index 0000000..7c6bce3
--- /dev/null
+++ b/arch/microblaze/kernel/init_task.c
@@ -0,0 +1,31 @@
+/*
+ * arch/microblaze/kernel/init_task.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+union thread_union init_thread_union
+ __attribute__((__section__(".data.init_task"))) =
+{ INIT_THREAD_INFO(init_task) };
+
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
new file mode 100644
index 0000000..679fe19
--- /dev/null
+++ b/arch/microblaze/kernel/process.c
@@ -0,0 +1,129 @@
+/*
+ * arch/microblaze/kernel/process.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+
+#include <asm/system.h>
+
+/* FIXME */
+void show_regs(struct pt_regs *regs)
+{
+ unsigned long *p;
+ int i;
+ printk(KERN_INFO "pc:\t0x%08lx\tsp:\t0x%08lx\n", regs->pc, regs->r1);
+ printk(KERN_INFO
+ "flags:\t0x%08lx\tear:\t0x%08lx\tesr:\t"
+ "0x%08lx\tfsr:\t0x%08lx\n",
+ regs->msr, regs->ear, regs->esr, regs->fsr);
+ printk(KERN_INFO
+ "r0:\t0x%08lx\tr1:\t0x%08lx\tr2:\t0x%08lx\tr3\t0x%08lx\n",
+ 0L, regs->r1, regs->r2, regs->r3);
+ for (i = 4, p = &(regs->r4); i < 32; i += 4, p += 4) {
+ printk(KERN_INFO "r%i:\t0x%08lx\tr%i:\t0x%08lx\tr%i:\t"
+ "0x%08lx\tr%i:\t0x%08lx\n",
+ i, *p, i+1, *(p+1), i+2, *(p+2), i+3, *(p+3));
+ }
+ printk(KERN_INFO "\n");
+}
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+void cpu_idle(void)
+{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
+ while (1) {
+ while (!need_resched())
+ cpu_relax();
+
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs = task_pt_regs(p);
+ struct thread_info *ti = task_thread_info(p);
+
+ *childregs = *regs;
+
+ if (user_mode(regs))
+ childregs->r1 = usp;
+ else
+ childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
+
+ memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+ ti->cpu_context.sp = (unsigned long)childregs;
+ ti->cpu_context.msr = (unsigned long)childregs->msr;
+ ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
+
+ if (clone_flags & CLONE_SETTLS)
+ ;/* FIXME: not sure what to do */
+
+ return 0;
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ * FIXME this needs to be checked
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ struct cpu_context *ctx =
+ &(((struct thread_info *)(tsk->stack))->cpu_context);
+
+ /* Check whether the thread is blocked in resume() */
+ if (in_sched_functions(ctx->r15))
+ return ((unsigned long)ctx->r15);
+ else
+ return ctx->r14;
+}
+
+static void kernel_thread_helper(int (*fn)(void *), void *arg)
+{
+ fn(arg);
+ do_exit(-1);
+}
+
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+ int ret;
+
+ memset(®s, 0, sizeof(regs));
+ /* store them in non-volatile registers */
+ regs.r5 = (unsigned long)fn;
+ regs.r6 = (unsigned long)arg;
+ local_save_flags(regs.msr);
+ regs.pc = (unsigned long)kernel_thread_helper;
+ regs.kernel_mode = 1;
+
+ ret = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ ®s, 0, NULL, NULL);
+
+ return ret;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+/* TBD (used by procfs) */
+ return 0;
+}
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 24/52] [microblaze] time support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (13 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 23/52] [microblaze] process and init task function monstr
@ 2008-01-24 15:02 ` monstr
[not found] ` <47BD86F3.9030400@petalogix.com>
2008-01-24 15:03 ` [PATCH 25/52] [microblaze] ptrace support monstr
` (36 subsequent siblings)
51 siblings, 1 reply; 67+ messages in thread
From: monstr @ 2008-01-24 15:02 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/time.c | 90 ++++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/delay.h | 28 ++++++++++++
include/asm-microblaze/timex.h | 21 +++++++++
3 files changed, 139 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/time.c
create mode 100644 include/asm-microblaze/delay.h
create mode 100644 include/asm-microblaze/timex.h
diff --git a/arch/microblaze/kernel/time.c b/arch/microblaze/kernel/time.c
new file mode 100644
index 0000000..d5ebdff
--- /dev/null
+++ b/arch/microblaze/kernel/time.c
@@ -0,0 +1,90 @@
+/*
+ * arch/microblaze/kernel/time.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/jiffies.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <asm/bug.h>
+#include <asm/setup.h>
+
+void time_init(void)
+{
+ system_timer_init();
+}
+
+int do_settimeofday(struct timespec *tv)
+{
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
+ write_seqlock_irq(&xtime_lock);
+
+ /* This is revolting. We need to set the xtime.tv_nsec
+ * correctly. However, the value in this location is
+ * is value at the last tick.
+ * Discover what correction gettimeofday
+ * would have done, and then undo it!
+ */
+#if 0
+ tv->tv_nsec -= mach_gettimeoffset() * 1000;
+#endif
+
+ while (tv->tv_nsec < 0) {
+ tv->tv_nsec += NSEC_PER_SEC;
+ tv->tv_sec--;
+ }
+
+ xtime.tv_sec = tv->tv_sec;
+ xtime.tv_nsec = tv->tv_nsec;
+
+ time_adjust = 0;
+ time_status |= STA_UNSYNC;
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
+
+ write_sequnlock_irq(&xtime_lock);
+ clock_was_set();
+ return 0;
+}
+EXPORT_SYMBOL(do_settimeofday);
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long seq;
+ unsigned long usec, sec;
+ /* unsigned long max_ntp_tick = tick_usec - tickadj; */
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+ usec = do_gettimeoffset();
+ sec = xtime.tv_sec;
+ usec += (xtime.tv_nsec / 1000);
+ } while (read_seqretry(&xtime_lock, seq));
+
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+}
+EXPORT_SYMBOL(do_gettimeofday);
+
+unsigned long long sched_clock(void)
+{
+ return (unsigned long long)jiffies * (1000000000 / HZ);
+}
diff --git a/include/asm-microblaze/delay.h b/include/asm-microblaze/delay.h
new file mode 100644
index 0000000..1eaa74c
--- /dev/null
+++ b/include/asm-microblaze/delay.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-microblaze/delay.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+extern inline void __delay(unsigned long loops)
+{
+ asm volatile ("# __delay \n\t" \
+ "1: addi %0, %0, -1 \t\n" \
+ "bneid %0, 1b \t\n" \
+ "nop \t\n"
+ : "=r" (loops)
+ : "0" (loops));
+}
+
+static inline void udelay(unsigned long usec)
+{
+}
+
+#endif /* _ASM_DELAY_H */
diff --git a/include/asm-microblaze/timex.h b/include/asm-microblaze/timex.h
new file mode 100644
index 0000000..17d2f11
--- /dev/null
+++ b/include/asm-microblaze/timex.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-microblaze/timex.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * FIXME -- need review
+ */
+
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
+
+typedef unsigned long cycles_t;
+
+#define get_cycles() (0)
+
+#endif /* _ASM_TIMEX_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 25/52] [microblaze] ptrace support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (14 preceding siblings ...)
2008-01-24 15:02 ` [PATCH 24/52] [microblaze] time support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 26/52] [microblaze] IPC support monstr
` (35 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/ptrace.c | 212 +++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/ptrace.h | 70 +++++++++++++
2 files changed, 282 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/ptrace.c
create mode 100644 include/asm-microblaze/ptrace.h
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
new file mode 100644
index 0000000..f2939ea
--- /dev/null
+++ b/arch/microblaze/kernel/ptrace.c
@@ -0,0 +1,212 @@
+/*
+ * arch/microblaze/kernel/ptrace.c -- `ptrace' system call
+ *
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2004-07 John Williams <john.williams@petalogix.com>
+ *
+ * derived from arch/v850/kernel/ptrace.c
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/asm-offsets.h>
+
+#if 0
+#define DBPRINTK(...) printk(__VA_ARGS__)
+#else
+#define DBPRINTK(...)
+#endif
+
+/* Returns the address where the register at REG_OFFS in P is stashed away. */
+static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
+ struct task_struct *t)
+{
+ struct pt_regs *regs;
+
+ /*
+ * Three basic cases:
+ *
+ * (1) A register normally saved before calling the scheduler, is
+ * available in the kernel entry pt_regs structure at the top
+ * of the kernel stack. The kernel trap/irq exit path takes
+ * care to save/restore almost all registers for ptrace'd
+ * processes.
+ *
+ * (2) A call-clobbered register, where the process P entered the
+ * kernel via [syscall] trap, is not stored anywhere; that's
+ * OK, because such registers are not expected to be preserved
+ * when the trap returns anyway (so we don't actually bother to
+ * test for this case).
+ *
+ * (3) A few registers not used at all by the kernel, and so
+ * normally never saved except by context-switches, are in the
+ * context switch state.
+ */
+
+ /* Register saved during kernel entry (or not available). */
+ regs = task_pt_regs(t);
+
+ return (microblaze_reg_t *)((char *)regs + reg_offs);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int rval;
+
+ switch (request) {
+ unsigned long val, copied;
+
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA:
+ DBPRINTK("PEEKTEXT/PEEKDATA at %08lX\n", addr);
+ copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+ rval = -EIO;
+ if (copied != sizeof(val))
+ break;
+ rval = put_user(val, (unsigned long *)data);
+ goto out;
+
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ DBPRINTK("POKETEXT/POKEDATA to %08lX\n", addr);
+ rval = 0;
+ if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ == sizeof(data))
+ break;
+ rval = -EIO;
+ goto out;
+
+ /* Read/write the word at location ADDR in the registers. */
+ case PTRACE_PEEKUSR:
+ case PTRACE_POKEUSR:
+ DBPRINTK("PEEKUSR/POKEUSR : 0x%08lx\n", addr);
+ rval = 0;
+ if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+ /* Special requests that don't actually correspond
+ to offsets in struct pt_regs. */
+ if (addr == PT_TEXT_ADDR) {
+ val = child->mm->start_code;
+ } else if (addr == PT_DATA_ADDR) {
+ val = child->mm->start_data;
+ } else if (addr == PT_TEXT_LEN) {
+ val = child->mm->end_code
+ - child->mm->start_code;
+ } else {
+ rval = -EIO;
+ }
+ } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+ microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
+ if (request == PTRACE_PEEKUSR) {
+ val = *reg_addr;
+ } else {
+ *reg_addr = data;
+ }
+ } else
+ rval = -EIO;
+
+ if (rval == 0 && request == PTRACE_PEEKUSR)
+ rval = put_user(val, (unsigned long *)data);
+ goto out;
+
+ /* Continue and stop at next (return from) syscall */
+ case PTRACE_SYSCALL:
+ DBPRINTK("PTRACE_SYSCALL\n");
+ case PTRACE_SINGLESTEP:
+ DBPRINTK("PTRACE_SINGLESTEP\n");
+ /* Restart after a signal. */
+ case PTRACE_CONT:
+ DBPRINTK("PTRACE_CONT\n");
+ rval = -EIO;
+ if (!valid_signal(data))
+ break;
+
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ child->exit_code = data;
+ DBPRINTK("wakeup_process\n");
+ wake_up_process(child);
+ rval = 0;
+ break;
+
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ DBPRINTK("PTRACE_KILL\n");
+ rval = 0;
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+ break;
+ child->exit_code = SIGKILL;
+ wake_up_process(child);
+ break;
+
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ DBPRINTK("PTRACE_DETACH\n");
+ rval = ptrace_detach(child, data);
+ break;
+
+ default:
+ rval = -EIO;
+ goto out;
+ }
+ out:
+ return rval;
+}
+
+#if 0
+static asmlinkage void syscall_trace(void)
+{
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+ /* The 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ ? 0x80 : 0));
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
+#endif
+
+void ptrace_disable(struct task_struct *child)
+{
+ /* nothing to do */
+}
diff --git a/include/asm-microblaze/ptrace.h b/include/asm-microblaze/ptrace.h
new file mode 100644
index 0000000..f583d72
--- /dev/null
+++ b/include/asm-microblaze/ptrace.h
@@ -0,0 +1,70 @@
+/*
+ * include/asm-microblaze/ptrace.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+
+typedef unsigned long microblaze_reg_t;
+
+struct pt_regs {
+ microblaze_reg_t r0;
+ microblaze_reg_t r1;
+ microblaze_reg_t r2;
+ microblaze_reg_t r3;
+ microblaze_reg_t r4;
+ microblaze_reg_t r5;
+ microblaze_reg_t r6;
+ microblaze_reg_t r7;
+ microblaze_reg_t r8;
+ microblaze_reg_t r9;
+ microblaze_reg_t r10;
+ microblaze_reg_t r11;
+ microblaze_reg_t r12;
+ microblaze_reg_t r13;
+ microblaze_reg_t r14;
+ microblaze_reg_t r15;
+ microblaze_reg_t r16;
+ microblaze_reg_t r17;
+ microblaze_reg_t r18;
+ microblaze_reg_t r19;
+ microblaze_reg_t r20;
+ microblaze_reg_t r21;
+ microblaze_reg_t r22;
+ microblaze_reg_t r23;
+ microblaze_reg_t r24;
+ microblaze_reg_t r25;
+ microblaze_reg_t r26;
+ microblaze_reg_t r27;
+ microblaze_reg_t r28;
+ microblaze_reg_t r29;
+ microblaze_reg_t r30;
+ microblaze_reg_t r31;
+ microblaze_reg_t pc;
+ microblaze_reg_t msr;
+ microblaze_reg_t ear;
+ microblaze_reg_t esr;
+ microblaze_reg_t fsr;
+ int kernel_mode;
+};
+
+#define kernel_mode(regs) ((regs)->kernel_mode)
+#define user_mode(regs) (!kernel_mode(regs))
+
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+extern void show_regs(struct pt_regs *);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PTRACE_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 26/52] [microblaze] IPC support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (15 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 25/52] [microblaze] ptrace support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 27/52] [microblaze] traps support monstr
` (34 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/sys_microblaze.c | 331 +++++++++++++++++++++++++++++++
include/asm-microblaze/ipc.h | 18 ++
include/asm-microblaze/ipcbuf.h | 38 ++++
3 files changed, 387 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/sys_microblaze.c
create mode 100644 include/asm-microblaze/ipc.h
create mode 100644 include/asm-microblaze/ipcbuf.h
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
new file mode 100644
index 0000000..a14328f
--- /dev/null
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -0,0 +1,331 @@
+/*
+ * arch/microblaze/kernel/sys_microblaze.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Copyright (C) 2007 PetaLogix
+ *
+ * Authors:
+ * John Williams <john.williams@petalogix.com>
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/syscalls.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <linux/ipc.h>
+#include <asm/semaphore.h>
+#include <asm/unistd.h>
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+int
+sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
+{
+ int version, ret;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ ret = -EINVAL;
+ switch (call) {
+ case SEMOP:
+ ret = sys_semop(first, (struct sembuf *)ptr, second);
+ break;
+ case SEMGET:
+ ret = sys_semget(first, second, third);
+ break;
+ case SEMCTL:
+ {
+ union semun fourth;
+
+ if (!ptr)
+ break;
+ if ((ret = access_ok(VERIFY_READ, ptr,
+ sizeof(long)) ? 0 : -EFAULT)
+ || (ret = get_user(fourth.__pad, (void **)ptr)))
+ break;
+ ret = sys_semctl(first, second, third, fourth);
+ break;
+ }
+ case MSGSND:
+ ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third);
+ break;
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+
+ if (!ptr)
+ break;
+ if ((ret = access_ok(VERIFY_READ, ptr,
+ sizeof(tmp)) ? 0 : -EFAULT)
+ || (ret = copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof(tmp))))
+ break;
+ ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp,
+ third);
+ break;
+ }
+ default:
+ ret = sys_msgrcv(first, (struct msgbuf *) ptr,
+ second, fifth, third);
+ break;
+ }
+ break;
+ case MSGGET:
+ ret = sys_msgget((key_t) first, second);
+ break;
+ case MSGCTL:
+ ret = sys_msgctl(first, second, (struct msqid_ds *) ptr);
+ break;
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+
+ if ((ret = access_ok(VERIFY_WRITE, (ulong *) third,
+ sizeof(ulong)) ? 0 : -EFAULT))
+ break;
+ ret = do_shmat(first, (char *) ptr, second, &raddr);
+ if (ret)
+ break;
+ ret = put_user(raddr, (ulong *) third);
+ break;
+ }
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ break;
+ ret = do_shmat(first, (char *) ptr, second,
+ (ulong *) third);
+ break;
+ }
+ break;
+ case SHMDT:
+ ret = sys_shmdt((char *)ptr);
+ break;
+ case SHMGET:
+ ret = sys_shmget(first, second, third);
+ break;
+ case SHMCTL:
+ ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
+ break;
+ }
+
+ return ret;
+}
+
+long execve(const char *filename, char **argv, char **envp)
+{
+ struct pt_regs regs;
+ int ret;
+
+ memset(®s, 0, sizeof(struct pt_regs));
+ local_save_flags(regs.msr);
+ ret = do_execve((char *)filename, (char __user * __user *)argv,
+ (char __user * __user *)envp, ®s);
+
+ if (ret < 0)
+ goto out;
+
+ /*
+ * Save argc to the register structure for userspace.
+ */
+ regs.r5 = ret; /* FIXME */
+
+ /*
+ * We were successful. We won't be returning to our caller, but
+ * instead to user space by manipulating the kernel stack.
+ */
+ asm volatile ("addk r5, r0, %0 \n\t"
+ "addk r6, r0, %1 \n\t"
+ /* copy regs to top of stack */
+ "brlid r15, memmove \n\t"
+ "addik r7, r0, %2 \n\t"
+ "brid ret_to_user \n\t"
+ /* reposition stack pointer */
+ "addk r1, r0, r3 \n\t"
+ :
+ : "r" (task_pt_regs(current)),
+ "r" (®s),
+ "i" (sizeof(regs))
+ : "r1", "r3", "r5", "r6", "r7", "r15", "memory");
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL(execve);
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
+ regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
+{
+ if (!stack)
+ stack = regs->r1;
+ return do_fork(flags, stack, regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
+{
+ int error;
+ char *filename;
+
+ filename = getname(filenamei);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+
+asmlinkage int sys_pipe(unsigned long __user *fildes)
+{
+ int fd[2];
+ int error;
+
+ error = do_pipe(fd);
+ if (!error) {
+ if (copy_to_user(fildes, fd, 2*sizeof(int)))
+ error = -EFAULT;
+ }
+ return error;
+}
+
+static inline unsigned long
+do_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ struct file *file = NULL;
+ int ret = -EBADF;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS))
+ if (!(file = fget(fd))) {
+ printk(KERN_INFO "no fd in mmap\r\n");
+ goto out;
+ }
+
+ down_write(¤t->mm->mmap_sem);
+ ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up_write(¤t->mm->mmap_sem);
+ if (file)
+ fput(file);
+out:
+ return ret;
+}
+
+unsigned long sys_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
+{
+ int err = -EINVAL;
+
+ if (offset & ~PAGE_MASK) {
+ printk(KERN_INFO "no pagemask in mmap\r\n");
+ goto out;
+ }
+
+ err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+ return err;
+}
+
+int sys_uname(struct old_utsname *name)
+{
+ int err = -EFAULT;
+
+ down_read(&uts_sem);
+ if (name && !copy_to_user(name, utsname(), sizeof(*name)))
+ err = 0;
+ up_read(&uts_sem);
+ return err;
+}
+
+int sys_olduname(struct oldold_utsname *name)
+{
+ int error;
+
+ if (!name)
+ return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ down_read(&uts_sem);
+ error = __copy_to_user(&name->sysname, utsname()->sysname,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->nodename, utsname()->nodename,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->release, utsname()->release,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->release + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->version, utsname()->version,
+ __OLD_UTS_LEN);
+ error -= __put_user(0, name->version + __OLD_UTS_LEN);
+ error -= __copy_to_user(&name->machine, utsname()->machine,
+ __OLD_UTS_LEN);
+ error = __put_user(0, name->machine + __OLD_UTS_LEN);
+ up_read(&uts_sem);
+
+ error = error ? -EFAULT : 0;
+ return error;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register const char *__a __asm__("r5") = filename;
+ register const void *__b __asm__("r6") = argv;
+ register const void *__c __asm__("r7") = envp;
+ register unsigned long __syscall __asm__("r12") = __NR_execve;
+ register unsigned long __ret __asm__("r3");
+ __asm__ __volatile__ ("brki r14, 0x8"
+ : "=r" (__ret), "=r" (__syscall)
+ : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+ : "r4", "r8", "r9",
+ "r10", "r11", "r14", "cc", "memory");
+ return __ret;
+}
diff --git a/include/asm-microblaze/ipc.h b/include/asm-microblaze/ipc.h
new file mode 100644
index 0000000..041b0eb
--- /dev/null
+++ b/include/asm-microblaze/ipc.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-microblaze/ipc.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IPC_H
+#define _ASM_IPC_H
+
+#include <asm-generic/ipc.h>
+
+#endif /* _ASM_IPC_H */
+
+
diff --git a/include/asm-microblaze/ipcbuf.h b/include/asm-microblaze/ipcbuf.h
new file mode 100644
index 0000000..742768d
--- /dev/null
+++ b/include/asm-microblaze/ipcbuf.h
@@ -0,0 +1,38 @@
+/*
+ * include/asm-microblaze/ipcbuf.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IPCBUF_H
+#define _ASM_IPCBUF_H
+
+/*
+ * The user_ipc_perm structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm {
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* _ASM_IPCBUF_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 27/52] [microblaze] traps support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (16 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 26/52] [microblaze] IPC support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 28/52] [microblaze] support for a.out monstr
` (33 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/traps.c | 88 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/traps.c
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
new file mode 100644
index 0000000..eb8202b
--- /dev/null
+++ b/arch/microblaze/kernel/traps.c
@@ -0,0 +1,88 @@
+/*
+ * arch/microblaze/kernel/traps.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <asm/exceptions.h>
+#include <asm/system.h>
+
+void trap_init(void)
+{
+ initialize_exception_handlers();
+ __enable_hw_exceptions();
+}
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+ printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+ __builtin_return_address(0), ptr, size);
+ BUG();
+}
+EXPORT_SYMBOL(__bad_xchg);
+
+static int kstack_depth_to_print = 24;
+
+void show_trace(struct task_struct *task, unsigned long *stack)
+{
+ unsigned long addr;
+
+ if (!stack)
+ stack = (unsigned long *)&stack;
+
+ printk(KERN_INFO "Call Trace: ");
+#ifdef CONFIG_KALLSYMS
+ printk(KERN_INFO "\n");
+#endif
+ while (!kstack_end(stack)) {
+ addr = *stack++;
+ if (__kernel_text_address(addr)) {
+ printk(KERN_INFO "[<%08lx>] ", addr);
+ print_symbol("%s\n", addr);
+ }
+ }
+ printk(KERN_INFO "\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+ unsigned long *stack;
+ int i;
+
+ if (sp == NULL) {
+ if (task)
+ sp = (unsigned long *) ((struct thread_info *)
+ (task->stack))->cpu_context.sp;
+ else
+ sp = (unsigned long *)&sp;
+ }
+
+ stack = sp;
+
+ printk(KERN_INFO "\nStack:\n ");
+
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (kstack_end(sp))
+ break;
+ if (i && ((i % 8) == 0))
+ printk("\n ");
+ printk("%08lx ", *sp++);
+ }
+ printk("\n");
+ show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+ show_stack(NULL, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 28/52] [microblaze] support for a.out
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (17 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 27/52] [microblaze] traps support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 29/52] [microblaze] memory inicialization, MMU, TLB monstr
` (32 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/a.out.h | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/a.out.h
diff --git a/include/asm-microblaze/a.out.h b/include/asm-microblaze/a.out.h
new file mode 100644
index 0000000..63046bd
--- /dev/null
+++ b/include/asm-microblaze/a.out.h
@@ -0,0 +1,14 @@
+/*
+ * include/asm-microblaze/a.out.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_A_OUT_H
+#define _ASM_A_OUT_H
+
+#endif /* _ASM_A_OUT_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 29/52] [microblaze] memory inicialization, MMU, TLB
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (18 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 28/52] [microblaze] support for a.out monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 30/52] [microblaze] consistent allocation & page.h, monstr
` (31 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/mm/init.c | 188 ++++++++++++++++++++++++++++++++++
include/asm-microblaze/mmu.h | 19 ++++
include/asm-microblaze/mmu_context.h | 24 +++++
include/asm-microblaze/tlb.h | 18 ++++
include/asm-microblaze/tlbflush.h | 22 ++++
5 files changed, 271 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/mm/init.c
create mode 100644 include/asm-microblaze/mmu.h
create mode 100644 include/asm-microblaze/mmu_context.h
create mode 100644 include/asm-microblaze/tlb.h
create mode 100644 include/asm-microblaze/tlbflush.h
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
new file mode 100644
index 0000000..ebb71bf
--- /dev/null
+++ b/arch/microblaze/mm/init.c
@@ -0,0 +1,188 @@
+/*
+ * arch/microblaze/mm/init.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/autoconf.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include "../../../mm/internal.h"
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <asm/sections.h>
+
+#include <asm/lmb.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+char *klimit = _end;
+static unsigned int memory_start;
+static unsigned int memory_end;
+unsigned int PAGE_OFFSET;
+
+void __init setup_memory(void)
+{
+ int i;
+ unsigned int start, end;
+ unsigned long map_size;
+ unsigned long start_pfn = 0;
+ unsigned long end_pfn = 0;
+
+ /* Find main memory where is the kernel */
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+ end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+ if ((start_pfn <= (((int)_text) >> PAGE_SHIFT)) &&
+ (((int)_text >> PAGE_SHIFT) <= end_pfn)) {
+ memory_end = (end_pfn << PAGE_SHIFT) - 1;
+ PAGE_OFFSET = memory_start = start_pfn << PAGE_SHIFT;
+ DBG("%s: Main mem: 0x%x-0x%x\n", __FUNCTION__,
+ memory_start, memory_end);
+ break;
+ }
+ }
+ /*
+ * start_pfn - start page - starting point
+ * end_pfn - first unused page
+ * memory_start - base physical address of main memory
+ * memory_end - end physical address of main memory
+ * PAGE_OFFSET - moving of first page
+ *
+ * Kernel:
+ * start: base phys address of kernel - page align
+ * end: base phys address of kernel - page align
+ *
+ * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
+ * max_low_pfn
+ * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
+ * num_physpages - number of all pages
+ *
+ */
+
+ /* reservation of region where is the kernel */
+ start = PFN_DOWN((int)_text) << PAGE_SHIFT;
+ end = PAGE_ALIGN((unsigned long)klimit);
+ lmb_reserve(start, end - start);
+ DBG("%s: kernel addr 0x%08x-0x%08x\n", __FUNCTION__, start, end);
+
+ /* calculate free pages, etc. */
+ min_low_pfn = PFN_UP(start_pfn << PAGE_SHIFT);
+ max_mapnr = PFN_DOWN((end_pfn << PAGE_SHIFT));
+ max_low_pfn = max_mapnr - min_low_pfn;
+ num_physpages = max_mapnr - min_low_pfn + 1;
+ printk(KERN_INFO "%s: max_mapnr: %#lx\n", __FUNCTION__, max_mapnr);
+ printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __FUNCTION__, min_low_pfn);
+ printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __FUNCTION__, max_low_pfn);
+
+ /* add place for data pages */
+ map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(end),
+ min_low_pfn, max_mapnr);
+ lmb_reserve(PFN_UP(end) << PAGE_SHIFT, map_size);
+
+ /* free bootmem is whole main memory */
+ free_bootmem(start_pfn << PAGE_SHIFT,
+ ((end_pfn - start_pfn) << PAGE_SHIFT) - 1);
+
+ /* reserve allocate blocks */
+ for (i = 1; i < lmb.reserved.cnt; i++) {
+ DBG("reserved %d - 0x%08x-0x%08x\n", i,
+ (u32) lmb.reserved.region[i].base,
+ (u32) lmb_size_bytes(&lmb.reserved, i));
+ reserve_bootmem(lmb.reserved.region[i].base,
+ lmb_size_bytes(&lmb.reserved, i) - 1);
+ }
+}
+
+void paging_init(void)
+{
+ int i;
+ unsigned long zones_size[MAX_NR_ZONES];
+
+ /* we can DMA to/from any address. put all page into
+ * ZONE_DMA. */
+ zones_size[ZONE_NORMAL] = max_low_pfn;
+
+ /* every other zones are empty */
+ for (i = 1; i < MAX_NR_ZONES; i++)
+ zones_size[i] = 0;
+
+ free_area_init_node(0, NODE_DATA(0), zones_size,
+ NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT, NULL);
+}
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+ unsigned long addr;
+
+ for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)addr, 0xcc, PAGE_SIZE);
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ int pages = 0;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ totalram_pages++;
+ pages++;
+ }
+ printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+ free_init_pages("unused kernel memory",
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
+}
+
+/* FIXME from arch/powerpc/mm/mem.c*/
+void show_mem(void)
+{
+ printk(KERN_NOTICE "%s\n", __FUNCTION__);
+}
+
+void __init mem_init(void)
+{
+ high_memory = (void *)(memory_end);
+
+ /* this will put all memory onto the freelists */
+ totalram_pages += free_all_bootmem();
+
+ printk(KERN_INFO "Memory: %luk/%luk available\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10));
+}
+
+/* Check against bounds of physical memory */
+int ___range_ok(unsigned long addr, unsigned long size)
+{
+ return ((addr < memory_start) ||
+ ((addr + size) >= memory_end));
+}
diff --git a/include/asm-microblaze/mmu.h b/include/asm-microblaze/mmu.h
new file mode 100644
index 0000000..c0d5e55
--- /dev/null
+++ b/include/asm-microblaze/mmu.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/mmu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+typedef struct {
+ struct vm_list_struct *vmlist;
+ unsigned long end_brk;
+} mm_context_t;
+
+#endif /* _ASM_MMU_H */
diff --git a/include/asm-microblaze/mmu_context.h b/include/asm-microblaze/mmu_context.h
new file mode 100644
index 0000000..ad499fd
--- /dev/null
+++ b/include/asm-microblaze/mmu_context.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-microblaze/mmu_context.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#define init_new_context(tsk, mm) ({ 0; })
+
+#define enter_lazy_tlb(mm, tsk) do {} while (0)
+#define change_mm_context(old, ctx, _pml4) do {} while (0)
+#define destroy_context(mm) do {} while (0)
+#define deactivate_mm(tsk, mm) do {} while (0)
+#define switch_mm(prev, next, tsk) do {} while (0)
+#define activate_mm(prev, next) do {} while (0)
+
+
+#endif /* _ASM_MMU_CONTEXT_H */
diff --git a/include/asm-microblaze/tlb.h b/include/asm-microblaze/tlb.h
new file mode 100644
index 0000000..5ae1b1c
--- /dev/null
+++ b/include/asm-microblaze/tlb.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-microblaze/tlb.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#define tlb_flush(tlb) do {} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TLB_H */
diff --git a/include/asm-microblaze/tlbflush.h b/include/asm-microblaze/tlbflush.h
new file mode 100644
index 0000000..57393ed
--- /dev/null
+++ b/include/asm-microblaze/tlbflush.h
@@ -0,0 +1,22 @@
+/*
+ * include/asm-microblaze/tlbflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#define flush_tlb() BUG()
+#define flush_tlb_all() BUG()
+#define flush_tlb_mm(mm) BUG()
+#define flush_tlb_page(vma, addr) BUG()
+#define flush_tlb_range(mm, start, end) BUG()
+#define flush_tlb_pgtables(mm, start, end) BUG()
+#define flush_tlb_kernel_range(start, end) BUG()
+
+#endif /* _ASM_TLBFLUSH_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 30/52] [microblaze] consistent allocation & page.h, ...
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (19 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 29/52] [microblaze] memory inicialization, MMU, TLB monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 31/52] [microblaze] pci header files monstr
` (30 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/mm/consistent.c | 176 ++++++++++++++++++++++++++++++++++++
include/asm-microblaze/page.h | 117 ++++++++++++++++++++++++
include/asm-microblaze/segment.h | 42 +++++++++
include/asm-microblaze/unaligned.h | 16 ++++
4 files changed, 351 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/mm/consistent.c
create mode 100644 include/asm-microblaze/page.h
create mode 100644 include/asm-microblaze/segment.h
create mode 100644 include/asm-microblaze/unaligned.h
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
new file mode 100644
index 0000000..fe7057b
--- /dev/null
+++ b/arch/microblaze/mm/consistent.c
@@ -0,0 +1,176 @@
+/*
+ * Microblaze support for cache consistent memory.
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * based on
+ *
+ * PowerPC version derived from arch/arm/mm/consistent.c
+ * Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ * linux/arch/arm/mm/consistent.c
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators. Used for DMA devices that want to
+ * share uncached memory with the processor core.
+ * My crufty no-MMU approach is simple. In the HW platform we can optionally
+ * mirror the DDR up above the processor cacheable region. So, memory accessed
+ * in this mirror region will not be cached. It's alloced from the same
+ * pool as normal memory, but the handle we return is shifted up into the
+ * uncached region. This will no doubt cause big problems if memory allocated
+ * here is not also freed properly. --JW
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/autoconf.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/dma-mapping.h>
+
+#include "../../../mm/internal.h" /* set_page_count */
+
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
+{
+ struct page *page, *end, *free;
+ unsigned long order;
+ void *ret, *virt;
+
+ if (in_interrupt())
+ BUG();
+
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = alloc_pages(gfp, order);
+ if (!page)
+ goto no_page;
+
+ /*
+ * We could do with a page_to_phys and page_to_bus here.
+ */
+ virt = page_address(page);
+ /* *dma_handle = virt_to_bus(virt); */
+ ret = ioremap(virt_to_phys(virt), size);
+ if (!ret)
+ goto no_remap;
+
+ /* Here's the magic! Note if the uncached shadow is not implemented,
+ it's up to the calling code to also test that condition and make
+ other arranegments, such as manually flushing the cache and so on.
+ */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+#endif
+ /* For !MMU, dma_handle is same as physical (shadowed) address */
+ *dma_handle = (dma_addr_t)ret;
+
+ /*
+ * free wasted pages. We skip the first page since we know
+ * that it will have count = 1 and won't require freeing.
+ * We also mark the pages in use as reserved so that
+ * remap_page_range works.
+ */
+ page = virt_to_page(virt);
+ free = page + (size >> PAGE_SHIFT);
+ end = page + (1 << order);
+
+ for (; page < end; page++) {
+ set_page_count(page, 1);
+ if (page >= free)
+ __free_page(page);
+ else
+ SetPageReserved(page);
+ }
+
+ return ret;
+no_remap:
+ __free_pages(page, order);
+no_page:
+ return NULL;
+}
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(void *vaddr)
+{
+ if (in_interrupt())
+ BUG();
+
+ /* Clear SHADOW_MASK bit in address, and free as per usual */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+#endif
+ vfree(vaddr);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+ unsigned long start;
+ unsigned long end;
+
+ start = (unsigned long)vaddr;
+
+ /* Convert start address back down to unshadowed memory region */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ start &= UNCACHED_SHADOW_MASK;
+#endif
+ end = start+size;
+
+ switch (direction) {
+ case PCI_DMA_NONE:
+ BUG();
+ case PCI_DMA_FROMDEVICE: /* invalidate only */
+ flush_dcache_range(start, end);
+ break;
+ case PCI_DMA_TODEVICE: /* writeback only */
+ flush_dcache_range(start, end);
+ break;
+ case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
+ flush_dcache_range(start, end);
+ break;
+ }
+}
+
+/*
+ * consistent_sync_page makes memory consistent. identical
+ * to consistent_sync, but takes a struct page instead of a
+ * virtual address
+ */
+void consistent_sync_page(struct page *page, unsigned long offset,
+ size_t size, int direction)
+{
+ unsigned long start = (unsigned long)page_address(page) + offset;
+ consistent_sync((void *)start, size, direction);
+}
diff --git a/include/asm-microblaze/page.h b/include/asm-microblaze/page.h
new file mode 100644
index 0000000..b3c891f
--- /dev/null
+++ b/include/asm-microblaze/page.h
@@ -0,0 +1,117 @@
+/*
+ * include/asm-microblaze/page.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#include <linux/autoconf.h>
+#include <linux/pfn.h>
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT (12)
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr) free_page(addr)
+
+#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
+#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) \
+ memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long ste[64]; } pmd_t;
+typedef struct { pmd_t pue[1]; } pud_t;
+typedef struct { pud_t pge[1]; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((x).ste[0])
+#define pud_val(x) ((x).pue[0])
+#define pgd_val(x) ((x).pge[0])
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) })
+#define __pmd(x) ((pmd_t) { (x) })
+#define __pgd(x) ((pgd_t) { (x) })
+#define __pgprot(x) ((pgprot_t) { (x) })
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size) _ALIGN_UP(addr, size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+extern unsigned int PAGE_OFFSET;
+
+/**
+ * Conversions for virtual address, physical address, pfn, and struct
+ * page are defined in the following files.
+ *
+ * virt -+
+ * | asm-microblaze/page.h
+ * phys -+
+ * | linux/pfn.h
+ * pfn -+
+ * | asm-generic/memory_model.h
+ * page -+
+ *
+ */
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#define __pa(vaddr) ((unsigned long) (vaddr))
+#define __va(paddr) ((void *) (paddr))
+
+#define phys_to_pfn(phys) (PFN_DOWN(phys))
+#define pfn_to_phys(pfn) (PFN_PHYS(pfn))
+
+#define virt_to_pfn(vaddr) (phys_to_pfn((__pa(vaddr))))
+#define pfn_to_virt(pfn) __va(pfn_to_phys((pfn)))
+
+#define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr)))
+#define page_to_virt(page) (pfn_to_virt(page_to_pfn(page)))
+
+#define page_to_phys(page) (pfn_to_phys(page_to_pfn(page)))
+#define page_to_bus(page) (page_to_phys(page))
+#define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr)))
+
+#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
+
+#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_PAGE_H */
diff --git a/include/asm-microblaze/segment.h b/include/asm-microblaze/segment.h
new file mode 100644
index 0000000..bd8b633
--- /dev/null
+++ b/include/asm-microblaze/segment.h
@@ -0,0 +1,42 @@
+/*
+ * include/asm-microblaze/segment.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ */
+
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+#define KERNEL_DS ((mm_segment_t){0})
+#define USER_DS KERNEL_DS
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (current_thread_info()->addr_limit)
+#define set_fs(x) \
+ do { current_thread_info()->addr_limit = (x); } while (0)
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_SEGMENT_H */
diff --git a/include/asm-microblaze/unaligned.h b/include/asm-microblaze/unaligned.h
new file mode 100644
index 0000000..edf79c2
--- /dev/null
+++ b/include/asm-microblaze/unaligned.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/unaligned.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <asm-generic/unaligned.h>
+
+#endif /* _ASM_UNALIGNED_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 31/52] [microblaze] pci header files
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (20 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 30/52] [microblaze] consistent allocation & page.h, monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 32/52] [microblaze] includes SHM*, msgbuf monstr
` (29 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/pci-bridge.h | 146 +++++++++++++++++++++++++++++++++++
include/asm-microblaze/pci.h | 139 +++++++++++++++++++++++++++++++++
2 files changed, 285 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/pci-bridge.h
create mode 100644 include/asm-microblaze/pci.h
diff --git a/include/asm-microblaze/pci-bridge.h b/include/asm-microblaze/pci-bridge.h
new file mode 100644
index 0000000..49d5dc4
--- /dev/null
+++ b/include/asm-microblaze/pci-bridge.h
@@ -0,0 +1,146 @@
+/*
+ * include/asm-microblaze/pci-bridge.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+#ifdef __KERNEL__
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pci_io_base returns the memory address at which you can access
+ * the I/O space for PCI bus number `bus' (or NULL on error).
+ */
+extern void __iomem *pci_bus_io_base(unsigned int bus);
+extern unsigned long pci_bus_io_base_phys(unsigned int bus);
+extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
+
+/* Allocate a new PCI host bridge structure */
+extern struct pci_controller *pcibios_alloc_controller(void);
+
+/* Helper function for setting up resources */
+extern void pci_init_resource(struct resource *res, unsigned long start,
+ unsigned long end, int flags, char *name);
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller *pci_bus_to_hose(int bus);
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller
+*pci_find_hose_for_OF_device(struct device_node *node);
+
+/* Fill up host controller resources from the OF node */
+extern void
+pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev, int primary);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+ int index; /* PCI domain number */
+ struct pci_controller *next;
+ struct pci_bus *bus;
+ void *arch_data;
+
+ int first_busno;
+ int last_busno;
+ int bus_offset;
+
+ void __iomem *io_base_virt;
+ unsigned long io_base_phys;
+
+ /* Some machines (PReP) have a non 1:1 mapping of
+ * the PCI memory space in the CPU bus space
+ */
+ unsigned long pci_mem_offset;
+
+ struct pci_ops *ops;
+ volatile unsigned int __iomem *cfg_addr;
+ volatile void __iomem *cfg_data;
+ /*
+ * If set, indirect method will set the cfg_type bit as
+ * needed to generate type 1 configuration transactions.
+ */
+ int set_cfg_type;
+
+ /* Currently, we limit ourselves to 1 IO range and 3 mem
+ * ranges since the common pci_bus structure can't handle more
+ */
+ struct resource io_resource;
+ struct resource mem_resources[3];
+ int mem_resource_count;
+
+ /* Host bridge I/O and Memory space
+ * Used for BAR placement algorithms
+ */
+ struct resource io_space;
+ struct resource mem_space;
+};
+
+/* These are used for config access before all the PCI probing
+ has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+ int where, u32 val);
+
+extern void setup_indirect_pci_nomap(struct pci_controller *hose,
+ void __iomem *cfg_addr, void __iomem *cfg_data);
+extern void setup_indirect_pci(struct pci_controller *hose,
+ u32 cfg_addr, u32 cfg_data);
+extern void setup_grackle(struct pci_controller *hose);
+
+extern unsigned char common_swizzle(struct pci_dev *, unsigned char *);
+
+/*
+ * The following code swizzles for exactly one bridge. The routine
+ * common_swizzle below handles multiple bridges. But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline unsigned char bridge_swizzle(unsigned char pin,
+ unsigned char idsel)
+{
+ return (((pin-1) + idsel) % 4) + 1;
+}
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those PPC systems that do not already have PCI
+ * interrupts properly routed.
+ */
+/* FIXME - double check this */
+#define PCI_IRQ_TABLE_LOOKUP \
+({ long _ctl_ = -1; \
+ if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+ _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+ _ctl_; })
+
+/*
+ * Scan the buses below a given PCI host bridge and assign suitable
+ * resources to all devices found.
+ */
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_PCI_BRIDGE_H */
diff --git a/include/asm-microblaze/pci.h b/include/asm-microblaze/pci.h
new file mode 100644
index 0000000..c7dac52
--- /dev/null
+++ b/include/asm-microblaze/pci.h
@@ -0,0 +1,139 @@
+/*
+ * include/asm-microblaze/pci.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _MICROBLAZE_PCI_H
+#define _MICROBLAZE_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
+struct pci_dev;
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall. */
+#define IOBASE_BRIDGE_NUMBER 0
+#define IOBASE_MEMORY 1
+#define IOBASE_IO 2
+#define IOBASE_ISA_IO 3
+#define IOBASE_ISA_MEM 4
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers
+ */
+extern int pci_assign_all_busses;
+
+#define pcibios_assign_all_busses() (pci_assign_all_busses)
+#define pcibios_scan_all_fns(a, b) 0
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0x10000000
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+ /* We don't do dynamic PCI IRQ allocation */
+}
+
+extern unsigned long pci_resource_to_bus(struct pci_dev *pdev,
+ struct resource *res);
+
+/*
+ * The PCI bus bridge can translate addresses issued by the processor(s)
+ * into a different address on the PCI bus. On 32-bit cpus, we assume
+ * this mapping is 1-1, but on 64-bit systems it often isn't.
+ *
+ * Obsolete ! Drivers should now use pci_resource_to_bus
+ */
+extern unsigned long phys_to_bus(unsigned long pa);
+extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr);
+extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
+
+/* The PCI address space does equal the physical memory
+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME) (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME) (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+ enum pci_dma_burst_strategy *strat,
+ unsigned long *strategy_parameter)
+{
+ *strat = PCI_DMA_BURST_INFINITY;
+ *strategy_parameter = ~0UL;
+}
+#endif
+
+/*
+ * At present there are very few 32-bit PPC machines that can have
+ * memory above the 4GB point, and we don't support that.
+ */
+#define pci_dac_dma_supported(pci_dev, mask) (0)
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return 0;
+}
+
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP 1
+
+extern void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res);
+
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region);
+
+/* extern void pcibios_add_platform_entries(struct pci_dev *dev); */
+
+struct file;
+extern pgprot_t pci_phys_mem_access_prot(struct file *file,
+ unsigned long offset,
+ unsigned long size,
+ pgprot_t prot);
+
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+ const struct resource *rsrc,
+ u64 *start, u64 *end);
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _MICROBLAZE_PCI_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 32/52] [microblaze] includes SHM*, msgbuf
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (21 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 31/52] [microblaze] pci header files monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 33/52] [microblaze] bug headers files monstr
` (28 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/msgbuf.h | 41 +++++++++++++++++++++++++++++
include/asm-microblaze/shmbuf.h | 52 +++++++++++++++++++++++++++++++++++++
include/asm-microblaze/shmparam.h | 16 +++++++++++
3 files changed, 109 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/msgbuf.h
create mode 100644 include/asm-microblaze/shmbuf.h
create mode 100644 include/asm-microblaze/shmparam.h
diff --git a/include/asm-microblaze/msgbuf.h b/include/asm-microblaze/msgbuf.h
new file mode 100644
index 0000000..3f4d164
--- /dev/null
+++ b/include/asm-microblaze/msgbuf.h
@@ -0,0 +1,41 @@
+/*
+ * include/asm-microblaze/msgbuf.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+ __kernel_time_t msg_stime; /* last msgsnd time */
+ unsigned long __unused1;
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+ unsigned long __unused2;
+ __kernel_time_t msg_ctime; /* last change time */
+ unsigned long __unused3;
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif /* _ASM_MSGBUF_H */
diff --git a/include/asm-microblaze/shmbuf.h b/include/asm-microblaze/shmbuf.h
new file mode 100644
index 0000000..5571e2f
--- /dev/null
+++ b/include/asm-microblaze/shmbuf.h
@@ -0,0 +1,52 @@
+/*
+ * include/asm-microblaze/shmbuf.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ unsigned long __unused1;
+ __kernel_time_t shm_dtime; /* last detach time */
+ unsigned long __unused2;
+ __kernel_time_t shm_ctime; /* last change time */
+ unsigned long __unused3;
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
diff --git a/include/asm-microblaze/shmparam.h b/include/asm-microblaze/shmparam.h
new file mode 100644
index 0000000..752498c
--- /dev/null
+++ b/include/asm-microblaze/shmparam.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/shmparam.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 33/52] [microblaze] bug headers files
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (22 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 32/52] [microblaze] includes SHM*, msgbuf monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 34/52] [microblaze] definitions of types monstr
` (27 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/bug.h | 17 +++++++++++++++++
include/asm-microblaze/bugs.h | 19 +++++++++++++++++++
2 files changed, 36 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/bug.h
create mode 100644 include/asm-microblaze/bugs.h
diff --git a/include/asm-microblaze/bug.h b/include/asm-microblaze/bug.h
new file mode 100644
index 0000000..5e23942
--- /dev/null
+++ b/include/asm-microblaze/bug.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-microblaze/bug.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#include <linux/kernel.h>
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_BUG_H */
diff --git a/include/asm-microblaze/bugs.h b/include/asm-microblaze/bugs.h
new file mode 100644
index 0000000..558d27b
--- /dev/null
+++ b/include/asm-microblaze/bugs.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/bugs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_BUGS_H
+#define _ASM_BUGS_H
+
+static inline void check_bugs(void)
+{
+ /* nothing to do */
+}
+
+#endif /* _ASM_BUGS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 34/52] [microblaze] definitions of types
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (23 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 33/52] [microblaze] bug headers files monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 35/52] [microblaze] ioctl support monstr
` (26 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/posix_types.h | 75 ++++++++++++++++++++++++++++++++++
include/asm-microblaze/types.h | 64 +++++++++++++++++++++++++++++
2 files changed, 139 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/posix_types.h
create mode 100644 include/asm-microblaze/types.h
diff --git a/include/asm-microblaze/posix_types.h b/include/asm-microblaze/posix_types.h
new file mode 100644
index 0000000..a05f61f
--- /dev/null
+++ b/include/asm-microblaze/posix_types.h
@@ -0,0 +1,75 @@
+/*
+ * include/asm-microblaze/posix_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef int __kernel_daddr_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+ int val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+ int __val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef __FD_SET
+#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef __FD_CLR
+#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef __FD_ISSET
+#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* _ASM_POSIX_TYPES_H */
diff --git a/include/asm-microblaze/types.h b/include/asm-microblaze/types.h
new file mode 100644
index 0000000..3ba4b8d
--- /dev/null
+++ b/include/asm-microblaze/types.h
@@ -0,0 +1,64 @@
+/*
+ * include/asm-microblaze/types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef __signed__ char s8;
+typedef unsigned char u8;
+
+typedef __signed__ short s16;
+typedef unsigned short u16;
+
+typedef __signed__ int s32;
+typedef unsigned int u32;
+
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+#endif/* __KERNEL__ */
+#endif
+
+#endif /* _ASM_TYPES_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 35/52] [microblaze] ioctl support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (24 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 34/52] [microblaze] definitions of types monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 36/52] [microblaze] io.h IO operations monstr
` (25 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/ioctl.h | 84 +++++++++++++++++++++++++++++++++++
include/asm-microblaze/ioctls.h | 93 +++++++++++++++++++++++++++++++++++++++
2 files changed, 177 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/ioctl.h
create mode 100644 include/asm-microblaze/ioctls.h
diff --git a/include/asm-microblaze/ioctl.h b/include/asm-microblaze/ioctl.h
new file mode 100644
index 0000000..c65a664
--- /dev/null
+++ b/include/asm-microblaze/ioctl.h
@@ -0,0 +1,84 @@
+/*
+ * include/asm-microblaze/ioctl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _MICROBLAZE_IOCTL_H
+#define _MICROBLAZE_IOCTL_H
+
+/*
+ * this was copied from the alpha as it's a bit cleaner there.
+ * -- Cort
+ */
+
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+#define _IOC_SIZEBITS 13
+#define _IOC_DIRBITS 3
+
+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _IOC_NONE 1U
+#define _IOC_READ 2U
+#define _IOC_WRITE 4U
+
+#define _IOC(dir, type, nr, size) \
+ (((dir) << _IOC_DIRSHIFT) | \
+ ((type) << _IOC_TYPESHIFT) | \
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
+/* provoke compile error for invalid uses of size argument */
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _IOC_TYPECHECK(t) \
+ ((sizeof(t) == sizeof(t[1]) && \
+ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+ sizeof(t) : __invalid_size_argument_for_IOC)
+
+/* used to create numbers */
+#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0)
+#define _IOR(type, nr, size) \
+ _IOC(_IOC_READ, (type), (nr), (_IOC_TYPECHECK(size)))
+#define _IOW(type, nr, size) \
+ _IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
+#define _IOWR(type, nr, size) \
+ _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type, nr, size) \
+ _IOC(_IOC_READ, (type), (nr), sizeof(size))
+#define _IOW_BAD(type, nr, size) \
+ _IOC(_IOC_WRITE, (type), (nr), sizeof(size))
+#define _IOWR_BAD(type, nr, size) \
+ _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), sizeof(size))
+
+/* used to decode them.. */
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* various drivers, such as the pcmcia stuff, need these... */
+#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
+
+#endif /* _MICROBLAZE_IOCTL_H */
diff --git a/include/asm-microblaze/ioctls.h b/include/asm-microblaze/ioctls.h
new file mode 100644
index 0000000..2ea08e0
--- /dev/null
+++ b/include/asm-microblaze/ioctls.h
@@ -0,0 +1,93 @@
+/*
+ * include/asm-microblaze/ioctls.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IOCTLS_H
+#define _ASM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCGSID 0x5429 /* Return the session ID of FD */
+/* Get Pty Number (of pty-mux device) */
+#define TIOCGPTN _IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
+
+#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+
+#define FIOQSIZE 0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+#endif /* _ASM_IOCTLS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 36/52] [microblaze] io.h IO operations
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (25 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 35/52] [microblaze] ioctl support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 37/52] [microblaze] headers for executables format FLAT, ELF monstr
` (24 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/io.h | 210 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 210 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/io.h
diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h
new file mode 100644
index 0000000..a0a5401
--- /dev/null
+++ b/include/asm-microblaze/io.h
@@ -0,0 +1,210 @@
+/*
+ * include/asm-microblaze/io.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <asm/byteorder.h>
+#include <asm/page.h>
+
+static inline unsigned char __raw_readb(const volatile void *addr)
+{
+ return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short __raw_readw(const volatile void *addr)
+{
+ return *(volatile unsigned short __force *)addr;
+}
+static inline unsigned int __raw_readl(const volatile void *addr)
+{
+ return *(volatile unsigned int __force *)addr;
+}
+static inline unsigned long __raw_readq(const volatile void *addr)
+{
+ return *(volatile unsigned long __force *)addr;
+}
+static inline void __raw_writeb(unsigned char v, volatile void *addr)
+{
+ *(volatile unsigned char __force *)addr = v;
+}
+static inline void __raw_writew(unsigned short v, volatile void *addr)
+{
+ *(volatile unsigned short __force *)addr = v;
+}
+static inline void __raw_writel(unsigned int v, volatile void *addr)
+{
+ *(volatile unsigned int __force *)addr = v;
+}
+static inline void __raw_writeq(unsigned long v, volatile void *addr)
+{
+ *(volatile unsigned long __force *)addr = v;
+}
+
+/*
+ * read (readb, readw, readl, readq) and write (writeb, writew,
+ * writel, writeq) accessors are for PCI and thus littel endian.
+ * Linux 2.4 for Microblaze had this wrong.
+ */
+static inline unsigned char readb(const volatile void *addr)
+{
+ return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short readw(const volatile void *addr)
+{
+ return le16_to_cpu(*(volatile unsigned short __force *)addr);
+}
+static inline unsigned int readl(const volatile void *addr)
+{
+ return le32_to_cpu(*(volatile unsigned int __force *)addr);
+}
+static inline void writeb(unsigned char v, volatile void *addr)
+{
+ *(volatile unsigned char __force *)addr = v;
+}
+static inline void writew(unsigned short v, volatile void *addr)
+{
+ *(volatile unsigned short __force *)addr = cpu_to_le16(v);
+}
+static inline void writel(unsigned int v, volatile void __iomem *addr)
+{
+ *(volatile unsigned int __force *)addr = cpu_to_le32(v);
+}
+
+/* ioread and iowrite variants. thease are for now same as __raw_
+ * variants of accessors. we might check for endianess in the feature
+ */
+#define ioread8(addr) __raw_readb((u8 *)(addr))
+#define ioread16(addr) __raw_readw((u16 *)(addr))
+#define ioread32(addr) __raw_readl((u32 *)(addr))
+#define iowrite8(v, addr) __raw_writeb((u8)(v), (u8 *)(addr))
+#define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr))
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+#define inb(port) readb((u8 *)((port)))
+#define outb(val, port) writeb((val), (u8 *)((unsigned long)(port)))
+#define inw(port) readw((u16 *)((port)))
+#define outw(val, port) writew((val), (u16 *)((unsigned long)(port)))
+#define inl(port) readl((u32 *)((port)))
+#define outl(val, port) writel((val), (u32 *)((unsigned long)(port)))
+
+#define inb_p(port) inb((port))
+#define outb_p(val, port) outb((val), (port))
+#define inw_p(port) inw((port))
+#define outw_p(val, port) outw((val), (port))
+#define inl_p(port) inl((port))
+#define outl_p(val, port) outl((val), (port))
+
+#define memset_io(a, b, c) memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
+
+/**
+ * virt_to_phys - map virtual addresses to physical
+ * @address: address to remap
+ *
+ * The returned physical address is the physical (CPU) mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses directly mapped or allocated via kmalloc.
+ *
+ * This function does not give bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline unsigned long __iomem virt_to_phys(volatile void *address)
+{
+ return __pa((unsigned long)address);
+}
+
+#define virt_to_bus virt_to_phys
+
+/**
+ * phys_to_virt - map physical address to virtual
+ * @address: address to remap
+ *
+ * The returned virtual address is a current CPU mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses that have a kernel mapping
+ *
+ * This function does not handle bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+ return (void *)__va(address);
+}
+
+#define bus_to_virt(a) phys_to_virt(a)
+
+static inline void *__ioremap(unsigned long address, unsigned long size,
+ unsigned long flags)
+{
+ return (void *)address;
+}
+
+
+#define IO_SPACE_LIMIT ~(0UL)
+
+#define ioremap(physaddr, size) ((void *)(unsigned long)(physaddr))
+#define iounmap(addr) ((void)0)
+#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+/*
+ * Big Endian
+ */
+#define out_be32(a, v) __raw_writel((v), (a))
+#define out_be16(a, v) __raw_writew((v), (a))
+
+#define in_be32(a) __raw_readl(a)
+#define in_be16(a) __raw_readw(a)
+
+/*
+ * Little endian
+ */
+
+#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a));
+#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a))
+
+#define in_le32(a) __le32_to_cpu(__raw_readl(a))
+#define in_le16(a) __le16_to_cpu(__raw_readw(a))
+
+/* Byte ops */
+#define out_8(a, v) __raw_writeb((v), (a))
+#define in_8(a) __raw_readb(a)
+
+/* FIXME */
+static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+ return (void __iomem *) (port);
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+ /* Nothing to do */
+}
+
+#endif /* _ASM_IO_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 37/52] [microblaze] headers for executables format FLAT, ELF
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (26 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 36/52] [microblaze] io.h IO operations monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 38/52] [microblaze] dma support monstr
` (23 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/elf.h | 24 +++++++++++
include/asm-microblaze/flat.h | 93 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/elf.h
create mode 100644 include/asm-microblaze/flat.h
diff --git a/include/asm-microblaze/elf.h b/include/asm-microblaze/elf.h
new file mode 100644
index 0000000..8b95630
--- /dev/null
+++ b/include/asm-microblaze/elf.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-microblaze/elf.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_ELF_H
+#define _ASM_ELF_H
+
+#define EM_XILINX_MICROBLAZE 0xbaab
+#define ELF_ARCH EM_XILINX_MICROBLAZE
+
+#define elf_check_arch(x) ((x)->e_machine == EM_XILINX_MICROBLAZE)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+
+#endif /* _ASM_ELF_H */
diff --git a/include/asm-microblaze/flat.h b/include/asm-microblaze/flat.h
new file mode 100644
index 0000000..1f50a97
--- /dev/null
+++ b/include/asm-microblaze/flat.h
@@ -0,0 +1,93 @@
+/*
+ * include/asm-microblaze/flat.h
+ *
+ * uClinux flat-format executables
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_FLAT_H
+#define _MICROBLAZE_FLAT_H
+
+#include <asm/unaligned.h>
+
+#define flat_stack_align(sp) /* nothing needed */
+#define flat_argvp_envp_on_stack() 0
+#define flat_old_ram_flag(flags) (flags)
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_set_persistent(relval, p) 0
+
+/*
+ * Microblaze works a little differently from other arches, because
+ * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
+ * over two instructions, an 'imm' instruction which provides the top
+ * 16 bits, then the instruction "proper" which provides the low 16
+ * bits.
+ */
+
+/*
+ * Crack open a symbol reference and extract the address to be
+ * relocated. rp is a potentially unaligned pointer to the
+ * reference
+ */
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
+ unsigned long flags, unsigned long *persistent)
+{
+ unsigned long addr;
+ (void)flags;
+
+ /* Is it a split 64/32 reference? */
+ if (relval & 0x80000000) {
+ /* Grab the two halves of the reference */
+ unsigned long val_hi, val_lo;
+
+ val_hi = get_unaligned(rp);
+ val_lo = get_unaligned(rp+1);
+
+ /* Crack the address out */
+ addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+ } else {
+ /* Get the address straight out */
+ addr = get_unaligned(rp);
+ }
+
+ return addr;
+}
+
+/*
+ * Insert an address into the symbol reference at rp. rp is potentially
+ * unaligned.
+ */
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+ /* Is this a split 64/32 reloc? */
+ if (relval & 0x80000000) {
+ /* Get the two "halves" */
+ unsigned long val_hi = get_unaligned(rp);
+ unsigned long val_lo = get_unaligned(rp + 1);
+
+ /* insert the address */
+ val_hi = (val_hi & 0xffff0000) | addr >> 16;
+ val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
+
+ /* store the two halves back into memory */
+ put_unaligned(val_hi, rp);
+ put_unaligned(val_lo, rp+1);
+ } else {
+ /* Put it straight in, no messing around */
+ put_unaligned(addr, rp);
+ }
+}
+
+#define flat_get_relocate_addr(rel) (rel & 0x7fffffff)
+
+#endif /* _MICROBLAZE_FLAT_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 38/52] [microblaze] dma support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (27 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 37/52] [microblaze] headers for executables format FLAT, ELF monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 39/52] [microblaze] headers for irq monstr
` (22 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/dma-mapping.h | 124 ++++++++++++++++++++++++++++++++++
include/asm-microblaze/dma.h | 21 ++++++
include/asm-microblaze/scatterlist.h | 21 ++++++
3 files changed, 166 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/dma-mapping.h
create mode 100644 include/asm-microblaze/dma.h
create mode 100644 include/asm-microblaze/scatterlist.h
diff --git a/include/asm-microblaze/dma-mapping.h b/include/asm-microblaze/dma-mapping.h
new file mode 100644
index 0000000..defe1c4
--- /dev/null
+++ b/include/asm-microblaze/dma-mapping.h
@@ -0,0 +1,124 @@
+/*
+ * include/asm-microblaze/dma-mapping.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <asm/io.h>
+#include <asm/bug.h>
+
+struct scatterlist;
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
+void consistent_free(void *vaddr);
+void consistent_sync(void *vaddr, size_t size, int direction);
+void consistent_sync_page(struct page *page, unsigned long offset,
+ size_t size, int direction);
+
+/* FIXME */
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ return 0;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, int flag)
+{
+ return consistent_alloc(flag, size, dma_handle);
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ BUG();
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+
+ return virt_to_bus(ptr);
+}
+
+#define dma_unmap_single(dev, addr, size, dir) do { } while (0)
+
+
+#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-microblaze/dma.h b/include/asm-microblaze/dma.h
new file mode 100644
index 0000000..a0c5c41
--- /dev/null
+++ b/include/asm-microblaze/dma.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-microblaze/dma.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+/* we don't have dma address limit. define it as zero to be
+ * unlimited. */
+#define MAX_DMA_ADDRESS (0)
+
+#define ISA_DMA_THRESHOLD (0)
+
+
+#endif /* _ASM_DMA_H */
diff --git a/include/asm-microblaze/scatterlist.h b/include/asm-microblaze/scatterlist.h
new file mode 100644
index 0000000..389bdc8
--- /dev/null
+++ b/include/asm-microblaze/scatterlist.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-microblaze/scatterlist.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+struct scatterlist {
+ unsigned long page_link;
+ unsigned int offset;
+ dma_addr_t dma_address;
+ unsigned int length;
+};
+
+#endif /* _ASM_SCATTERLIST_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 39/52] [microblaze] headers for irq
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (28 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 38/52] [microblaze] dma support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 40/52] [microblaze] atomic.h bitops.h byteorder.h monstr
` (21 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/hardirq.h | 31 +++++++++++++++++++++++++++++++
include/asm-microblaze/hw_irq.h | 19 +++++++++++++++++++
include/asm-microblaze/irq_regs.h | 19 +++++++++++++++++++
3 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/hardirq.h
create mode 100644 include/asm-microblaze/hw_irq.h
create mode 100644 include/asm-microblaze/irq_regs.h
diff --git a/include/asm-microblaze/hardirq.h b/include/asm-microblaze/hardirq.h
new file mode 100644
index 0000000..61cd3c0
--- /dev/null
+++ b/include/asm-microblaze/hardirq.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-microblaze/hardirq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_HARDIRQ_H
+#define _ASM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/current.h>
+#include <asm/ptrace.h>
+
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(struct pt_regs *regs);
+
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+void ack_bad_irq(unsigned int irq);
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#endif /* _ASM_HARDIRQ_H */
diff --git a/include/asm-microblaze/hw_irq.h b/include/asm-microblaze/hw_irq.h
new file mode 100644
index 0000000..e7a0956
--- /dev/null
+++ b/include/asm-microblaze/hw_irq.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/hw_irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+ /* Nothing to do */
+}
+
+#endif /* _ASM_HW_IRQ_H */
diff --git a/include/asm-microblaze/irq_regs.h b/include/asm-microblaze/irq_regs.h
new file mode 100644
index 0000000..702b051
--- /dev/null
+++ b/include/asm-microblaze/irq_regs.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/irq_regs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IRQ_REGS_H
+#define _ASM_IRQ_REGS_H
+
+#include <asm-generic/irq_regs.h>
+
+#endif /* _ASM_IRQ_REGS_H */
+
+
+
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 40/52] [microblaze] atomic.h bitops.h byteorder.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (29 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 39/52] [microblaze] headers for irq monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 41/52] [microblaze] headers pgalloc.h pgtable.h monstr
` (20 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/atomic.h | 108 ++++++++++++++++++++++++++++++++++++
include/asm-microblaze/bitops.h | 29 ++++++++++
include/asm-microblaze/byteorder.h | 23 ++++++++
3 files changed, 160 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/atomic.h
create mode 100644 include/asm-microblaze/bitops.h
create mode 100644 include/asm-microblaze/byteorder.h
diff --git a/include/asm-microblaze/atomic.h b/include/asm-microblaze/atomic.h
new file mode 100644
index 0000000..f7be329
--- /dev/null
+++ b/include/asm-microblaze/atomic.h
@@ -0,0 +1,108 @@
+/*
+ * include/asm-microblaze/atomic.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/compiler.h> /* likely */
+#include <asm/system.h> /* local_irq_XXX and friends */
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = (i))
+
+#define atomic_inc(v) (atomic_add_return(1, (v)))
+#define atomic_dec(v) (atomic_sub_return(1, (v)))
+
+#define atomic_add(i, v) (atomic_add_return(i, (v)))
+#define atomic_sub(i, v) (atomic_sub_return(i, (v)))
+
+#define atomic_inc_return(v) (atomic_add_return(1, (v)))
+#define atomic_dec_return(v) (atomic_sub_return(1, (v)))
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+
+ c = atomic_read(v);
+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+ c = old;
+ return c != u;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *addr &= ~mask;
+ local_irq_restore(flags);
+}
+
+/**
+ * atomic_add_return - add and return
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static __inline__ int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ local_irq_save(flags);
+ val = v->counter;
+ v->counter = val += i;
+ local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ return atomic_add_return(-i, v);
+}
+
+#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#include <asm-generic/atomic.h>
+
+#endif /* _ASM_ATOMIC_H */
diff --git a/include/asm-microblaze/bitops.h b/include/asm-microblaze/bitops.h
new file mode 100644
index 0000000..4078d90
--- /dev/null
+++ b/include/asm-microblaze/bitops.h
@@ -0,0 +1,29 @@
+/*
+ * include/asm-microblaze/auxvec.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _MICROBLAZE_BITOPS_H
+#define _MICROBLAZE_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/autoconf.h>
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+#include <asm-generic/bitops.h>
+
+#endif /* _MICROBLAZE_BITOPS_H */
diff --git a/include/asm-microblaze/byteorder.h b/include/asm-microblaze/byteorder.h
new file mode 100644
index 0000000..df9dbbe
--- /dev/null
+++ b/include/asm-microblaze/byteorder.h
@@ -0,0 +1,23 @@
+/*
+ * include/asm-microblaze/byteorder.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __BYTEORDER_HAS_U64__
+#define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 41/52] [microblaze] headers pgalloc.h pgtable.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (30 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 40/52] [microblaze] atomic.h bitops.h byteorder.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 42/52] [microblaze] system.h pvr.h processor.h monstr
` (19 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/pgalloc.h | 16 ++++++++++++
include/asm-microblaze/pgtable.h | 50 ++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/pgalloc.h
create mode 100644 include/asm-microblaze/pgtable.h
diff --git a/include/asm-microblaze/pgalloc.h b/include/asm-microblaze/pgalloc.h
new file mode 100644
index 0000000..c6fd99d
--- /dev/null
+++ b/include/asm-microblaze/pgalloc.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/pgalloc.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#define check_pgt_cache() do {} while (0)
+
+#endif /* _ASM_PGALLOC_H */
diff --git a/include/asm-microblaze/pgtable.h b/include/asm-microblaze/pgtable.h
new file mode 100644
index 0000000..6e9db76
--- /dev/null
+++ b/include/asm-microblaze/pgtable.h
@@ -0,0 +1,50 @@
+/*
+ * include/asm-microblaze/pgtable.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#define pgd_present(pgd) (1) /* pages are always present on NO_MM */
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr) (1)
+#define pmd_offset(a, b) ((void *) 0)
+
+#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
+
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif
+
+#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
+
+#define swapper_pg_dir ((pgd_t *) NULL)
+
+#define pgtable_cache_init() do {} while (0)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define arch_enter_lazy_cpu_mode() do {} while (0)
+
+void paging_init(void);
+
+#endif /* _ASM_PGTABLE_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 42/52] [microblaze] system.h pvr.h processor.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (31 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 41/52] [microblaze] headers pgalloc.h pgtable.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 43/52] [microblaze] clinkage.h linkage.h sections.h kmap_types.h monstr
` (18 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/processor.h | 89 +++++++++++++++++
include/asm-microblaze/pvr.h | 185 ++++++++++++++++++++++++++++++++++++
include/asm-microblaze/system.h | 185 ++++++++++++++++++++++++++++++++++++
3 files changed, 459 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/processor.h
create mode 100644 include/asm-microblaze/pvr.h
create mode 100644 include/asm-microblaze/system.h
diff --git a/include/asm-microblaze/processor.h b/include/asm-microblaze/processor.h
new file mode 100644
index 0000000..15cda64
--- /dev/null
+++ b/include/asm-microblaze/processor.h
@@ -0,0 +1,89 @@
+/*
+ * include/asm-microblaze/processor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+
+/*
+ * User space process size: memory size
+ *
+ * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both
+ * user processes and the kernel is on the same memory region. They
+ * both share the memory space and that is limited by the amount of
+ * physical memory. thus, we set TASK_SIZE == amount of total memory.
+ */
+
+#define TASK_SIZE (0x81000000 - 0x80000000)
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's. We won't be using it
+ */
+#define TASK_UNMAPPED_BASE 0
+
+struct task_struct;
+
+/* thread_struct is gone. use thread_info instead. */
+struct thread_struct { };
+#define INIT_THREAD { }
+
+/* Do necessary setup to start up a newly executed thread. */
+static inline void start_thread(struct pt_regs *regs,
+ unsigned long pc,
+ unsigned long usp)
+{
+ regs->pc = pc;
+ regs->r1 = usp;
+ regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Free all resources held by a thread. */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+/* FIXME */
+#define cpu_relax() do {} while (0)
+#define prepare_to_copy(tsk) do {} while (0)
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+/* #define task_thread_info(task) (task)->thread_info */
+/* #define task_stack_page(task) ((void*)((task)->thread_info)) */
+
+#define task_pt_regs(tsk) \
+ (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
+
+
+#define KSTK_EIP(tsk) (0)
+#define KSTK_ESP(tsk) (0)
+
+#endif /* _ASM_PROCESSOR_H */
diff --git a/include/asm-microblaze/pvr.h b/include/asm-microblaze/pvr.h
new file mode 100644
index 0000000..f76bb6e
--- /dev/null
+++ b/include/asm-microblaze/pvr.h
@@ -0,0 +1,185 @@
+/*
+ * include/asm-microblaze/pvr.h
+ *
+ * Support for the MicroBlaze PVR (Processor Version Register)
+ *
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+#ifndef _ASM_PVR_H
+#define _ASM_PVR_H
+
+#define PVR_MSR_BIT 0x400
+
+struct pvr_s {
+ unsigned pvr[16];
+};
+
+/* The following taken from Xilinx's standalone BSP pvr.h */
+
+/* Basic PVR mask */
+#define PVR0_PVR_FULL_MASK 0x80000000
+#define PVR0_USE_BARREL_MASK 0x40000000
+#define PVR0_USE_DIV_MASK 0x20000000
+#define PVR0_USE_HW_MUL_MASK 0x10000000
+#define PVR0_USE_FPU_MASK 0x08000000
+#define PVR0_USE_EXCEPTION_MASK 0x04000000
+#define PVR0_USE_ICACHE_MASK 0x02000000
+#define PVR0_USE_DCACHE_MASK 0x01000000
+#define PVR0_VERSION_MASK 0x0000FF00
+#define PVR0_USER1_MASK 0x000000FF
+
+/* User 2 PVR mask */
+#define PVR1_USER2_MASK 0xFFFFFFFF
+
+/* Configuration PVR masks */
+#define PVR2_D_OPB_MASK 0x80000000
+#define PVR2_D_LMB_MASK 0x40000000
+#define PVR2_I_OPB_MASK 0x20000000
+#define PVR2_I_LMB_MASK 0x10000000
+#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
+#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
+#define PVR2_USE_MSR_INSTR 0x00020000
+#define PVR2_USE_PCMP_INSTR 0x00010000
+#define PVR2_AREA_OPTIMISED 0x00008000
+#define PVR2_USE_BARREL_MASK 0x00004000
+#define PVR2_USE_DIV_MASK 0x00002000
+#define PVR2_USE_HW_MUL_MASK 0x00001000
+#define PVR2_USE_FPU_MASK 0x00000800
+#define PVR2_USE_MUL64_MASK 0x00000400
+#define PVR2_OPCODE_0x0_ILLEGAL_MASK 0x00000040
+#define PVR2_UNALIGNED_EXCEPTION_MASK 0x00000020
+#define PVR2_ILL_OPCODE_EXCEPTION_MASK 0x00000010
+#define PVR2_IOPB_BUS_EXCEPTION_MASK 0x00000008
+#define PVR2_DOPB_BUS_EXCEPTION_MASK 0x00000004
+#define PVR2_DIV_ZERO_EXCEPTION_MASK 0x00000002
+#define PVR2_FPU_EXCEPTION_MASK 0x00000001
+
+/* Debug and exception PVR masks */
+#define PVR3_DEBUG_ENABLED_MASK 0x80000000
+#define PVR3_NUMBER_OF_PC_BRK_MASK 0x1E000000
+#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK 0x00380000
+#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK 0x0000E000
+#define PVR3_FSL_LINKS_MASK 0x00000380
+
+/* ICache config PVR masks */
+#define PVR4_USE_ICACHE_MASK 0x80000000
+#define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR4_ICACHE_USE_FSL_MASK 0x02000000
+#define PVR4_ICACHE_ALLOW_WR_MASK 0x01000000
+#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000
+#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000
+
+/* DCache config PVR masks */
+#define PVR5_USE_DCACHE_MASK 0x80000000
+#define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR5_DCACHE_USE_FSL_MASK 0x02000000
+#define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000
+#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000
+#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000
+
+/* ICache base address PVR mask */
+#define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF
+
+/* ICache high address PVR mask */
+#define PVR7_ICACHE_HIGHADDR_MASK 0xFFFFFFFF
+
+/* DCache base address PVR mask */
+#define PVR8_DCACHE_BASEADDR_MASK 0xFFFFFFFF
+
+/* DCache high address PVR mask */
+#define PVR9_DCACHE_HIGHADDR_MASK 0xFFFFFFFF
+
+/* Target family PVR mask */
+#define PVR10_TARGET_FAMILY_MASK 0xFF000000
+
+/* MSR Reset value PVR mask */
+#define PVR11_MSR_RESET_VALUE_MASK 0x000007FF
+
+
+/* PVR access macros */
+#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK)
+#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK)
+#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK)
+#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
+#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK)
+#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
+#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
+#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
+#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK)
+#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK)
+
+#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK)
+#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK)
+#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK)
+#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK)
+#define PVR_INTERRUPT_IS_EDGE(pvr) \
+ (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
+#define PVR_EDGE_IS_POSITIVE(pvr) \
+ (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
+#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR)
+#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
+#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED)
+#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK)
+#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
+ (pvr.pvr[2] & PVR2_OPCODE_0x0_ILLEGAL_MASK)
+#define PVR_UNALIGNED_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_UNALIGNED_EXCEPTION_MASK)
+#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_ILL_OPCODE_EXCEPTION_MASK)
+#define PVR_IOPB_BUS_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_IOPB_BUS_EXCEPTION_MASK)
+#define PVR_DOPB_BUS_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_DOPB_BUS_EXCEPTION_MASK)
+#define PVR_DIV_ZERO_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_DIV_ZERO_EXCEPTION_MASK)
+#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXCEPTION_MASK)
+
+#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
+#define PVR_NUMBER_OF_PC_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
+#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
+#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
+#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
+
+#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
+ ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
+#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
+#define PVR_ICACHE_LINE_LEN(pvr) \
+ (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
+#define PVR_ICACHE_BYTE_SIZE(pvr) \
+ (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
+
+#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
+ ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
+#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
+#define PVR_DCACHE_LINE_LEN(pvr) \
+ (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
+#define PVR_DCACHE_BYTE_SIZE(pvr) \
+ (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
+
+
+#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
+#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+
+#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
+#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
+
+#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
+
+#define PVR_MSR_RESET_VALUE(pvr) \
+ (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
+
+int cpu_has_pvr(void);
+void get_pvr(struct pvr_s *pvr);
+
+#endif
diff --git a/include/asm-microblaze/system.h b/include/asm-microblaze/system.h
new file mode 100644
index 0000000..12fbb61
--- /dev/null
+++ b/include/asm-microblaze/system.h
@@ -0,0 +1,185 @@
+/*
+ * include/asm-microblaze/system.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <linux/autoconf.h>
+#include <asm/registers.h>
+
+struct task_struct;
+struct thread_info;
+
+extern struct task_struct *_switch_to(struct thread_info *prev,
+ struct thread_info *next);
+
+#define switch_to(prev, next, last) \
+ do { \
+ (last) = _switch_to(task_thread_info(prev), \
+ task_thread_info(next)); \
+ } while (0)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+
+#define local_irq_save(flags) \
+ do { \
+ asm volatile ("# local_irq_save \n\t" \
+ "msrclr %0, %1 \n\t" \
+ : "=r"(flags) \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_disable() \
+ do { \
+ asm volatile ("# local_irq_disable \n\t" \
+ "msrclr r0, %0 \n\t" \
+ : \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_enable() \
+ do { \
+ asm volatile ("# local_irq_enable \n\t" \
+ "msrset r0, %0 \n\t" \
+ : \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
+
+#define local_irq_save(flags) \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_save \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "andi %1, %0, %2 \n\t" \
+ "mts rmsr, %1 \n\t" \
+ "nop \n\t" \
+ : "=r"(flags), "=r" (tmp) \
+ : "i"(~MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_disable() \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_disable \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "andi %0, %0, %1 \n\t" \
+ "mts rmsr, %0 \n\t" \
+ "nop \n\t" \
+ : "=r"(tmp) \
+ : "i"(~MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_enable() \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_enable \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "ori %0, %0, %1 \n\t" \
+ "mts rmsr, %0 \n\t" \
+ "nop \n\t" \
+ : "=r"(tmp) \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define local_save_flags(flags) \
+ do { \
+ asm volatile ("# local_save_flags \n\t" \
+ "mfs %0, rmsr \n\t" \
+ : "=r"(flags) \
+ : \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_restore(flags) \
+ do { \
+ asm volatile ("# local_irq_restore \n\t"\
+ "mts rmsr, %0 \n\t" \
+ : \
+ :"r"(flags) \
+ : "memory"); \
+ } while (0)
+
+static inline int irqs_disabled(void)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+ return ((flags & MSR_IE) == 0);
+}
+
+#define smp_read_barrier_depends() do {} while (0)
+#define read_barrier_depends() do {} while (0)
+
+#define nop() asm volatile ("nop")
+#define mb() barrier()
+#define rmb() mb()
+#define wmb() mb()
+#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+
+void show_trace(struct task_struct *task, unsigned long *stack);
+void __bad_xchg(volatile void *ptr, int size);
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+ int size)
+{
+ unsigned long ret;
+ unsigned long flags;
+
+ switch (size) {
+ case 1:
+ local_irq_save(flags);
+ ret = *(volatile unsigned char *)ptr;
+ *(volatile unsigned char *)ptr = x;
+ local_irq_restore(flags);
+ break;
+
+ case 4:
+ local_irq_save(flags);
+ ret = *(volatile unsigned long *)ptr;
+ *(volatile unsigned long *)ptr = x;
+ local_irq_restore(flags);
+ break;
+ default:
+ __bad_xchg(ptr, size), ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+#define xchg(ptr,x) \
+ ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+extern void *cacheable_memcpy(void *, const void *, unsigned int);
+void free_init_pages(char *what, unsigned long begin, unsigned long end);
+void free_initmem(void);
+extern char *klimit;
+extern void ret_from_fork(void);
+
+#ifdef CONFIG_MTD_UCLINUX_EBSS
+extern char *_ebss;
+#endif
+
+#endif /* _ASM_SYSTEM_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 43/52] [microblaze] clinkage.h linkage.h sections.h kmap_types.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (32 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 42/52] [microblaze] system.h pvr.h processor.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 44/52] [microblaze] stats headers monstr
` (17 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/clinkage.h | 29 +++++++++++++++++++++++++++++
include/asm-microblaze/kmap_types.h | 31 +++++++++++++++++++++++++++++++
include/asm-microblaze/linkage.h | 17 +++++++++++++++++
include/asm-microblaze/sections.h | 19 +++++++++++++++++++
4 files changed, 96 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/clinkage.h
create mode 100644 include/asm-microblaze/kmap_types.h
create mode 100644 include/asm-microblaze/linkage.h
create mode 100644 include/asm-microblaze/sections.h
diff --git a/include/asm-microblaze/clinkage.h b/include/asm-microblaze/clinkage.h
new file mode 100644
index 0000000..697c6ac
--- /dev/null
+++ b/include/asm-microblaze/clinkage.h
@@ -0,0 +1,29 @@
+/*
+ * include/asm-microblaze/clinkage.h
+ *
+ * Macros to reflect C symbol-naming conventions
+ *
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001,2002 NEC Corporatione
+ * Copyright (C) 2001,2002 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ * Microblaze port by John Williams
+ */
+
+#ifndef _MICROBLAZE_CLINKAGE_H
+#define _MICROBLAZE_CLINKAGE_H
+
+#define __ASSEMBLY__
+
+#include <linux/linkage.h>
+
+#define C_SYMBOL_NAME(name) name
+#define C_ENTRY(name) .globl name; .align 4; name
+#define C_END(name)
+
+#endif /* _MICROBLAZE_CLINKAGE_H */
diff --git a/include/asm-microblaze/kmap_types.h b/include/asm-microblaze/kmap_types.h
new file mode 100644
index 0000000..9258c0b
--- /dev/null
+++ b/include/asm-microblaze/kmap_types.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-microblaze/kmap_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR,
+};
+
+#endif /* _ASM_KMAP_TYPES_H */
diff --git a/include/asm-microblaze/linkage.h b/include/asm-microblaze/linkage.h
new file mode 100644
index 0000000..c699956
--- /dev/null
+++ b/include/asm-microblaze/linkage.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-microblaze/linkage.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_LINKAGE_H
+#define _ASM_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif /* _ASM_LINKAGE_H */
diff --git a/include/asm-microblaze/sections.h b/include/asm-microblaze/sections.h
new file mode 100644
index 0000000..43df5f6
--- /dev/null
+++ b/include/asm-microblaze/sections.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/sections.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SECTIONS_H
+#define _ASM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _ssbss[], _esbss[];
+extern unsigned long __ivt_start[], __ivt_end[];
+
+#endif /* _ASM_SECTIONS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 44/52] [microblaze] stats headers
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (33 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 43/52] [microblaze] clinkage.h linkage.h sections.h kmap_types.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 45/52] [microblaze] termbits.h termios.h monstr
` (16 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/stat.h | 75 +++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/statfs.h | 16 ++++++++
2 files changed, 91 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/stat.h
create mode 100644 include/asm-microblaze/statfs.h
diff --git a/include/asm-microblaze/stat.h b/include/asm-microblaze/stat.h
new file mode 100644
index 0000000..a8702ab
--- /dev/null
+++ b/include/asm-microblaze/stat.h
@@ -0,0 +1,75 @@
+/*
+ * include/asm-microblaze/stat.h
+ *
+ * Microblaze stat structure
+ *
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+#include <asm/posix_types.h>
+
+struct stat {
+ unsigned int st_dev;
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long __unused1;
+ unsigned long st_mtime;
+ unsigned long __unused2;
+ unsigned long st_ctime;
+ unsigned long __unused3;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct stat64 {
+ unsigned long long st_dev;
+ unsigned long __unused1;
+
+ unsigned long long st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned long long st_rdev;
+ unsigned long __unused3;
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ unsigned long st_blocks; /* No. of 512-byte blocks allocated */
+ unsigned long __unused4; /* future possible st_blocks high bits */
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long __unused8;
+};
+
+#endif /* _ASM_STAT_H */
diff --git a/include/asm-microblaze/statfs.h b/include/asm-microblaze/statfs.h
new file mode 100644
index 0000000..9487a1e
--- /dev/null
+++ b/include/asm-microblaze/statfs.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/statfs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_STATFS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 45/52] [microblaze] termbits.h termios.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (34 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 44/52] [microblaze] stats headers monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 46/52] [microblaze] sigcontext.h siginfo.h monstr
` (15 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/termbits.h | 203 +++++++++++++++++++++++++++++++++++++
include/asm-microblaze/termios.h | 86 ++++++++++++++++
2 files changed, 289 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/termbits.h
create mode 100644 include/asm-microblaze/termios.h
diff --git a/include/asm-microblaze/termbits.h b/include/asm-microblaze/termbits.h
new file mode 100644
index 0000000..cdc7ec1
--- /dev/null
+++ b/include/asm-microblaze/termbits.h
@@ -0,0 +1,203 @@
+/*
+ * include/asm-microblaze/termbits.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TERMBITS_H
+#define _ASM_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+
+/* c_cc characters */
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* _ASM_TERMBITS_H */
diff --git a/include/asm-microblaze/termios.h b/include/asm-microblaze/termios.h
new file mode 100644
index 0000000..05488cf
--- /dev/null
+++ b/include/asm-microblaze/termios.h
@@ -0,0 +1,86 @@
+/*
+ * include/asm-microblaze/termios.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <linux/string.h>
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+#ifdef __KERNEL__
+/* intr=^C quit=^| erase=del kill=^U
+ eof=^D vtime=\0 vmin=\1 sxtc=\0
+ start=^Q stop=^S susp=^Z eol=\0
+ reprint=^R discard=^U werase=^W lnext=^V
+ eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* Modem lines */
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* Line disciplines */
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964 9 /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards
+ about SMS messages */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14
+#define N_HCI 15 /* Bluetooth HCI UART */
+
+#include <asm-generic/termios.h>
+
+#endif /* _ASM_TERMIOS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 46/52] [microblaze] sigcontext.h siginfo.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (35 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 45/52] [microblaze] termbits.h termios.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 47/52] [microblaze] headers simple files monstr
` (14 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/sigcontext.h | 21 +++++++++++++++++++++
include/asm-microblaze/siginfo.h | 17 +++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/sigcontext.h
create mode 100644 include/asm-microblaze/siginfo.h
diff --git a/include/asm-microblaze/sigcontext.h b/include/asm-microblaze/sigcontext.h
new file mode 100644
index 0000000..edb53f2
--- /dev/null
+++ b/include/asm-microblaze/sigcontext.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-microblaze/sigcontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+struct sigcontext {
+ struct pt_regs regs;
+ unsigned long oldmask;
+};
+
+#endif /* _ASM_SIGCONTEXT_H */
diff --git a/include/asm-microblaze/siginfo.h b/include/asm-microblaze/siginfo.h
new file mode 100644
index 0000000..ade99c0
--- /dev/null
+++ b/include/asm-microblaze/siginfo.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-microblaze/siginfo.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_SIGINFO_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 47/52] [microblaze] headers simple files
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (36 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 46/52] [microblaze] sigcontext.h siginfo.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 48/52] [microblaze] headers files entry.h current.h mman.h registers.h sembuf.h monstr
` (13 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/auxvec.h | 14 ++++++++++++++
include/asm-microblaze/cputime.h | 16 ++++++++++++++++
include/asm-microblaze/div64.h | 16 ++++++++++++++++
include/asm-microblaze/emergency-restart.h | 16 ++++++++++++++++
include/asm-microblaze/errno.h | 16 ++++++++++++++++
include/asm-microblaze/futex.h | 16 ++++++++++++++++
include/asm-microblaze/kdebug.h | 19 +++++++++++++++++++
include/asm-microblaze/local.h | 16 ++++++++++++++++
include/asm-microblaze/mutex.h | 16 ++++++++++++++++
include/asm-microblaze/namei.h | 24 ++++++++++++++++++++++++
include/asm-microblaze/percpu.h | 16 ++++++++++++++++
include/asm-microblaze/resource.h | 16 ++++++++++++++++
include/asm-microblaze/user.h | 18 ++++++++++++++++++
13 files changed, 219 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/auxvec.h
create mode 100644 include/asm-microblaze/cputime.h
create mode 100644 include/asm-microblaze/div64.h
create mode 100644 include/asm-microblaze/emergency-restart.h
create mode 100644 include/asm-microblaze/errno.h
create mode 100644 include/asm-microblaze/futex.h
create mode 100644 include/asm-microblaze/kdebug.h
create mode 100644 include/asm-microblaze/local.h
create mode 100644 include/asm-microblaze/mutex.h
create mode 100644 include/asm-microblaze/namei.h
create mode 100644 include/asm-microblaze/percpu.h
create mode 100644 include/asm-microblaze/resource.h
create mode 100644 include/asm-microblaze/user.h
diff --git a/include/asm-microblaze/auxvec.h b/include/asm-microblaze/auxvec.h
new file mode 100644
index 0000000..4d55bac
--- /dev/null
+++ b/include/asm-microblaze/auxvec.h
@@ -0,0 +1,14 @@
+/*
+ * include/asm-microblaze/auxvec.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_AUXVEC_H
+#define _ASM_AUXVEC_H
+
+#endif /* _ASM_AUXVEC_H */
diff --git a/include/asm-microblaze/cputime.h b/include/asm-microblaze/cputime.h
new file mode 100644
index 0000000..e4f104d
--- /dev/null
+++ b/include/asm-microblaze/cputime.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/cputime.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_CPUTIME_H
+#define _ASM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _ASM_CPUTIME_H */
diff --git a/include/asm-microblaze/div64.h b/include/asm-microblaze/div64.h
new file mode 100644
index 0000000..4de2a4a
--- /dev/null
+++ b/include/asm-microblaze/div64.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/div64.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_DIV64_H
+#define _ASM_DIV64_H
+
+#include <asm-generic/div64.h>
+
+#endif /* _ASM_DIV64_H */
diff --git a/include/asm-microblaze/emergency-restart.h b/include/asm-microblaze/emergency-restart.h
new file mode 100644
index 0000000..fb8aae4
--- /dev/null
+++ b/include/asm-microblaze/emergency-restart.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/emergency-restart.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-microblaze/errno.h b/include/asm-microblaze/errno.h
new file mode 100644
index 0000000..42831c2
--- /dev/null
+++ b/include/asm-microblaze/errno.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/errno.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_ERRNO_H */
diff --git a/include/asm-microblaze/futex.h b/include/asm-microblaze/futex.h
new file mode 100644
index 0000000..4f47480
--- /dev/null
+++ b/include/asm-microblaze/futex.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/futex.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif /* _ASM_FUTEX_H */
diff --git a/include/asm-microblaze/kdebug.h b/include/asm-microblaze/kdebug.h
new file mode 100644
index 0000000..2b809ae
--- /dev/null
+++ b/include/asm-microblaze/kdebug.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/kdebug.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ */
+
+#ifndef _ASM_KDEBUG_H
+#define _ASM_KDEBUG_H
+
+#include <asm-generic/kdebug.h>
+
+#endif /* _ASM_KDEBUG_H */
+
+
+
diff --git a/include/asm-microblaze/local.h b/include/asm-microblaze/local.h
new file mode 100644
index 0000000..f74d600
--- /dev/null
+++ b/include/asm-microblaze/local.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/local.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_LOCAL_H
+#define _ASM_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_LOCAL_H */
diff --git a/include/asm-microblaze/mutex.h b/include/asm-microblaze/mutex.h
new file mode 100644
index 0000000..cf51475
--- /dev/null
+++ b/include/asm-microblaze/mutex.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/mutex.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+#include <asm-generic/mutex-dec.h>
+
+#endif /* _ASM_MUTEX_H */
diff --git a/include/asm-microblaze/namei.h b/include/asm-microblaze/namei.h
new file mode 100644
index 0000000..9012c00
--- /dev/null
+++ b/include/asm-microblaze/namei.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-microblaze/namei.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_NAMEI_H
+#define _ASM_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+#define __emul_prefix() NULL
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_NAMEI_H */
diff --git a/include/asm-microblaze/percpu.h b/include/asm-microblaze/percpu.h
new file mode 100644
index 0000000..7f7a170
--- /dev/null
+++ b/include/asm-microblaze/percpu.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/percpu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PERCPU_H
+#define _ASM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_PERCPU_H */
diff --git a/include/asm-microblaze/resource.h b/include/asm-microblaze/resource.h
new file mode 100644
index 0000000..066a4ce
--- /dev/null
+++ b/include/asm-microblaze/resource.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-microblaze/resource.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_RESOURCE_H */
diff --git a/include/asm-microblaze/user.h b/include/asm-microblaze/user.h
new file mode 100644
index 0000000..bed2e1b
--- /dev/null
+++ b/include/asm-microblaze/user.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-microblaze/user.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * Authors:
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
+ */
+
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#endif /* _ASM_USER_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 48/52] [microblaze] headers files entry.h current.h mman.h registers.h sembuf.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (37 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 47/52] [microblaze] headers simple files monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 49/52] [microblaze] device.h param.h topology.h monstr
` (12 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/current.h | 25 +++++++++++++++++++++++++
include/asm-microblaze/entry.h | 32 ++++++++++++++++++++++++++++++++
include/asm-microblaze/mman.h | 27 +++++++++++++++++++++++++++
include/asm-microblaze/registers.h | 26 ++++++++++++++++++++++++++
include/asm-microblaze/sembuf.h | 36 ++++++++++++++++++++++++++++++++++++
5 files changed, 146 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/current.h
create mode 100644 include/asm-microblaze/entry.h
create mode 100644 include/asm-microblaze/mman.h
create mode 100644 include/asm-microblaze/registers.h
create mode 100644 include/asm-microblaze/sembuf.h
diff --git a/include/asm-microblaze/current.h b/include/asm-microblaze/current.h
new file mode 100644
index 0000000..4ff2a0f
--- /dev/null
+++ b/include/asm-microblaze/current.h
@@ -0,0 +1,25 @@
+/*
+ * include/asm-microblaze/current.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Dedicate r31 to keeping the current task pointer
+ */
+register struct task_struct *current asm("r31");
+
+#define get_current() current
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff --git a/include/asm-microblaze/entry.h b/include/asm-microblaze/entry.h
new file mode 100644
index 0000000..e298888
--- /dev/null
+++ b/include/asm-microblaze/entry.h
@@ -0,0 +1,32 @@
+/*
+ * include/asm-microblaze/entry.h
+ *
+ * Definitions used by low-level trap handlers
+ *
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_ENTRY_H
+#define _MICROBLAZE_ENTRY_H
+
+
+#include <asm/percpu.h>
+#include <asm/ptrace.h>
+
+/* These are per-cpu variables required in entry.S, among other
+ places */
+
+DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+DECLARE_PER_CPU(unsigned int, SYSCALL_SAVE); /* Saved syscall number */
+
+#endif /* _MICROBLAZE_ENTRY_H */
diff --git a/include/asm-microblaze/mman.h b/include/asm-microblaze/mman.h
new file mode 100644
index 0000000..7abf722
--- /dev/null
+++ b/include/asm-microblaze/mman.h
@@ -0,0 +1,27 @@
+/*
+ * include/asm-microblaze/mman.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MMAN_H
+#define _ASM_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+#define MAP_LOCKED 0x2000 /* pages are locked */
+#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+#endif /* _ASM_MMAN_H */
diff --git a/include/asm-microblaze/registers.h b/include/asm-microblaze/registers.h
new file mode 100644
index 0000000..98a27ae
--- /dev/null
+++ b/include/asm-microblaze/registers.h
@@ -0,0 +1,26 @@
+/*
+ * include/asm-microblaze/registers.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_REGISTERS_H
+#define _ASM_REGISTERS_H
+
+#define MSR_BE (1<<0)
+#define MSR_IE (1<<1)
+#define MSR_C (1<<2)
+#define MSR_BIP (1<<3)
+#define MSR_FSL (1<<4)
+#define MSR_ICE (1<<5)
+#define MSR_DZ (1<<6)
+#define MSR_DCE (1<<7)
+#define MSR_EE (1<<8)
+#define MSR_EIP (1<<9)
+#define MSR_CC (1<<31)
+
+#endif /* _ASM_REGISTERS_H */
diff --git a/include/asm-microblaze/sembuf.h b/include/asm-microblaze/sembuf.h
new file mode 100644
index 0000000..8d82db8
--- /dev/null
+++ b/include/asm-microblaze/sembuf.h
@@ -0,0 +1,36 @@
+/*
+ * include/asm-microblaze/sembuf.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+
+#endif /* _ASM_SEMBUF_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 49/52] [microblaze] device.h param.h topology.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (38 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 48/52] [microblaze] headers files entry.h current.h mman.h registers.h sembuf.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 50/52] [microblaze] pool.h socket.h monstr
` (11 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/device.h | 27 ++++++++
include/asm-microblaze/param.h | 36 +++++++++++
include/asm-microblaze/topology.h | 124 +++++++++++++++++++++++++++++++++++++
3 files changed, 187 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/device.h
create mode 100644 include/asm-microblaze/param.h
create mode 100644 include/asm-microblaze/topology.h
diff --git a/include/asm-microblaze/device.h b/include/asm-microblaze/device.h
new file mode 100644
index 0000000..c0e203c
--- /dev/null
+++ b/include/asm-microblaze/device.h
@@ -0,0 +1,27 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef _ASM_MICROBLAZE_DEVICE_H
+#define _ASM_MICROBLAZE_DEVICE_H
+
+struct dma_mapping_ops;
+struct device_node;
+
+struct dev_archdata {
+ /* Optional pointer to an OF device node */
+ struct device_node *of_node;
+
+ /* DMA operations on that device */
+ struct dma_mapping_ops *dma_ops;
+ void *dma_data;
+
+ /* NUMA node if applicable */
+ int numa_node;
+};
+
+#endif /* _ASM_MICROBLAZE_DEVICE_H */
+
+
diff --git a/include/asm-microblaze/param.h b/include/asm-microblaze/param.h
new file mode 100644
index 0000000..b79d739
--- /dev/null
+++ b/include/asm-microblaze/param.h
@@ -0,0 +1,36 @@
+/*
+ * include/asm-microblaze/param.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#ifdef __KERNEL__
+# define HZ 100 /* internal timer frequency */
+# define USER_HZ 100 /* for user interfaces in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */
+#endif
+
+#ifndef NGROUPS
+#define NGROUPS 32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#endif /* _ASM_PARAM_H */
diff --git a/include/asm-microblaze/topology.h b/include/asm-microblaze/topology.h
new file mode 100644
index 0000000..4d3e2e7
--- /dev/null
+++ b/include/asm-microblaze/topology.h
@@ -0,0 +1,124 @@
+/*
+ * include/asm-microblaze/topology.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_TOPOLOGY_H
+#define _ASM_TOPOLOGY_H
+#ifdef __KERNEL__
+
+struct sys_device;
+struct device_node;
+
+#ifdef CONFIG_NUMA
+
+#include <asm/mmzone.h>
+
+static inline int cpu_to_node(int cpu)
+{
+ return numa_cpu_lookup_table[cpu];
+}
+
+#define parent_node(node) (node)
+
+static inline cpumask_t node_to_cpumask(int node)
+{
+ return numa_cpumask_lookup_table[node];
+}
+
+static inline int node_to_first_cpu(int node)
+{
+ cpumask_t tmp;
+ tmp = node_to_cpumask(node);
+ return first_cpu(tmp);
+}
+
+int of_node_to_nid(struct device_node *device);
+
+struct pci_bus;
+#ifdef CONFIG_PCI
+extern int pcibus_to_node(struct pci_bus *bus);
+#else
+static inline int pcibus_to_node(struct pci_bus *bus)
+{
+ return -1;
+}
+#endif
+
+#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
+ CPU_MASK_ALL : \
+ node_to_cpumask(pcibus_to_node(bus)) \
+ )
+
+/* sched_domains SD_NODE_INIT for PPC64 machines */
+#define SD_NODE_INIT (struct sched_domain) { \
+ .span = CPU_MASK_NONE, \
+ .parent = NULL, \
+ .child = NULL, \
+ .groups = NULL, \
+ .min_interval = 8, \
+ .max_interval = 32, \
+ .busy_factor = 32, \
+ .imbalance_pct = 125, \
+ .cache_nice_tries = 1, \
+ .busy_idx = 3, \
+ .idle_idx = 1, \
+ .newidle_idx = 2, \
+ .wake_idx = 1, \
+ .flags = SD_LOAD_BALANCE \
+ | SD_BALANCE_EXEC \
+ | SD_BALANCE_NEWIDLE \
+ | SD_WAKE_IDLE \
+ | SD_SERIALIZE \
+ | SD_WAKE_BALANCE, \
+ .last_balance = jiffies, \
+ .balance_interval = 1, \
+ .nr_balance_failed = 0, \
+}
+
+extern void __init dump_numa_cpu_topology(void);
+
+extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
+extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
+
+#else
+
+static inline int of_node_to_nid(struct device_node *device)
+{
+ return 0;
+}
+
+static inline void dump_numa_cpu_topology(void) {}
+
+static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid)
+{
+ return 0;
+}
+
+static inline void sysfs_remove_device_from_node(struct sys_device *dev,
+ int nid)
+{
+}
+
+#include <asm-generic/topology.h>
+
+#endif /* CONFIG_NUMA */
+
+#ifdef CONFIG_SMP
+#include <asm/cputable.h>
+#define smt_capable() (cpu_has_feature(CPU_FTR_SMT))
+
+#ifdef CONFIG_PPC64
+#include <asm/smp.h>
+
+#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#endif
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_TOPOLOGY_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 50/52] [microblaze] pool.h socket.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (39 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 49/52] [microblaze] device.h param.h topology.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 51/52] [microblaze] fcntl.h sockios.h ucontext.h unistd.h monstr
` (10 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/poll.h | 37 +++++++++++++++++++++++
include/asm-microblaze/socket.h | 62 +++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/poll.h
create mode 100644 include/asm-microblaze/socket.h
diff --git a/include/asm-microblaze/poll.h b/include/asm-microblaze/poll.h
new file mode 100644
index 0000000..1fdc80b
--- /dev/null
+++ b/include/asm-microblaze/poll.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/poll.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+#define POLLRDNORM 0x0040
+#define POLLRDBAND 0x0080
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND 0x0100
+
+#define POLLMSG 0x0400
+#define POLLREMOVE 0x0800
+#define POLLRDHUP 0x2000
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#endif /* _ASM_POLL_H */
diff --git a/include/asm-microblaze/socket.h b/include/asm-microblaze/socket.h
new file mode 100644
index 0000000..6491b0b
--- /dev/null
+++ b/include/asm-microblaze/socket.h
@@ -0,0 +1,62 @@
+/*
+ * include/asm-microblaze/socket.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_ACCEPTCONN 30
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+
+#endif /* _ASM_SOCKET_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 51/52] [microblaze] fcntl.h sockios.h ucontext.h unistd.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (40 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 50/52] [microblaze] pool.h socket.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 52/52] [microblaze] setup.h string.h thread_info.h monstr
` (9 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/fcntl.h | 104 +++++++
include/asm-microblaze/sockios.h | 23 ++
include/asm-microblaze/ucontext.h | 24 ++
include/asm-microblaze/unistd.h | 548 +++++++++++++++++++++++++++++++++++++
4 files changed, 699 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/fcntl.h
create mode 100644 include/asm-microblaze/sockios.h
create mode 100644 include/asm-microblaze/ucontext.h
create mode 100644 include/asm-microblaze/unistd.h
diff --git a/include/asm-microblaze/fcntl.h b/include/asm-microblaze/fcntl.h
new file mode 100644
index 0000000..2b1fff2
--- /dev/null
+++ b/include/asm-microblaze/fcntl.h
@@ -0,0 +1,104 @@
+/*
+ * include/asm-microblaze/fcntl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _MICROBLAZE_FCNTL_H
+#define _MICROBLAZE_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define FASYNC 020000 /* fcntl, for BSD compatibility */
+#define O_DIRECTORY 040000 /* must be a directory */
+#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_LARGEFILE 0200000
+#define O_DIRECT 0400000 /* direct disk access hint */
+#define O_NOATIME 01000000
+#define O_CLOEXEC 02000000
+
+#define F_DUPFD 0 /* dup */
+#define F_GETFD 1 /* get close_on_exec */
+#define F_SETFD 2 /* set/clear close_on_exec */
+#define F_GETFL 3 /* get file->f_flags */
+#define F_SETFL 4 /* set file->f_flags */
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN 8 /* for sockets. */
+#define F_GETOWN 9 /* for sockets. */
+#define F_SETSIG 10 /* for sockets. */
+#define F_GETSIG 11 /* for sockets. */
+
+#define F_GETLK64 12 /* using 'struct flock64' */
+#define F_SETLK64 13
+#define F_SETLKW64 14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+/* for leases */
+#define F_INPROGRESS 16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* or'd with one of the above to prevent blocking */
+#define LOCK_UN 8 /* remove lock */
+
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
+#ifdef __KERNEL__
+#define F_POSIX 1
+#define F_FLOCK 2
+#define F_BROKEN 4 /* broken flock() emulation */
+#endif /* __KERNEL__ */
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+};
+
+struct flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE 1024
+
+#endif /* _MICROBLAZE_FCNTL_H */
diff --git a/include/asm-microblaze/sockios.h b/include/asm-microblaze/sockios.h
new file mode 100644
index 0000000..079e166
--- /dev/null
+++ b/include/asm-microblaze/sockios.h
@@ -0,0 +1,23 @@
+/*
+ * include/asm-microblaze/sockios.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SOCKIOS_H
+#define _ASM_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp */
+
+#endif /* _ASM_SOCKIOS_H */
diff --git a/include/asm-microblaze/ucontext.h b/include/asm-microblaze/ucontext.h
new file mode 100644
index 0000000..da464cf
--- /dev/null
+++ b/include/asm-microblaze/ucontext.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-microblaze/ucontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _ASM_UCONTEXT_H */
diff --git a/include/asm-microblaze/unistd.h b/include/asm-microblaze/unistd.h
new file mode 100644
index 0000000..abaa2b7
--- /dev/null
+++ b/include/asm-microblaze/unistd.h
@@ -0,0 +1,548 @@
+/*
+ * include/asm-microblaze/unistd.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_UNISTD_H
+#define _ASM_UNISTD_H
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86old 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_vm86 166
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188 /* some people actually want streams */
+#define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_madvise1 219 /* delete when C lib stub is removed */
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+/* 223 is unused */
+#define __NR_gettid 224
+#define __NR_readahead 225
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area 243
+#define __NR_get_thread_area 244
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+#define __NR_fadvise64 250
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
+#define __NR_timer_create 259
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
+#define __NR_tgkill 270
+#define __NR_utimes 271
+#define __NR_fadvise64_64 272
+#define __NR_vserver 273
+#define __NR_mbind 274
+#define __NR_get_mempolicy 275
+#define __NR_set_mempolicy 276
+#define __NR_mq_open 277
+#define __NR_mq_unlink (__NR_mq_open+1)
+#define __NR_mq_timedsend (__NR_mq_open+2)
+#define __NR_mq_timedreceive (__NR_mq_open+3)
+#define __NR_mq_notify (__NR_mq_open+4)
+#define __NR_mq_getsetattr (__NR_mq_open+5)
+#define __NR_kexec_load 283
+#define __NR_waitid 284
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd 322
+#define __NR_eventfd 323
+#define __NR_fallocate 324
+
+#define NR_syscalls 324
+
+/*
+ * user-visible error numbers are in the range -1 - -128: see
+ * <asm-generic/errno.h>
+ *
+ * both i386 and microblaze use generic version * of errno.h. the
+ * generic version of errno.h has more than 128 of * numbers. not
+ * sure what the comment means.
+ *
+ * following code is taken from mb 2.4
+ */
+#define __syscall_return(type, res) \
+do { \
+ /* user-visible error numbers are in the range -1 - -124: \
+ see <asm-microblaze/errno.h> */ \
+ if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+ errno = -(res); \
+ res = -1; \
+ } \
+ return (type) (res); \
+} while (0)
+
+#define _syscall0(type, name) \
+type name(void) \
+{ \
+ long __ret; \
+ asm volatile ("addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall1(type, name, type1, arg1) \
+type name(type1 arg1) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall2(type, name, type1, arg1, type2, arg2) \
+type name(type1 arg1, type2 arg2) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addk r6, r0, %3 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1), \
+ "r" ((long)arg2) \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
+type name(type1 arg1, type2 arg2, type3 arg3) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addk r6, r0, %3 \n\t" \
+ "addk r7, r0, %4 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1), \
+ "r" ((long)arg2), \
+ "r" ((long)arg3) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addk r6, r0, %3 \n\t" \
+ "addk r7, r0, %4 \n\t" \
+ "addk r8, r0, %5 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1), \
+ "r" ((long)arg2), \
+ "r" ((long)arg3), \
+ "r" ((long)arg4) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4, type5, arg5) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addk r6, r0, %3 \n\t" \
+ "addk r7, r0, %4 \n\t" \
+ "addk r8, r0, %5 \n\t" \
+ "addk r9, r0, %6 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1), \
+ "r" ((long)arg2), \
+ "r" ((long)arg3), \
+ "r" ((long)arg4), \
+ "r" ((long)arg5) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4, type5, arg5, type6, arg6) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, \
+ type6 arg6) \
+{ \
+ long __ret; \
+ asm volatile ("addk r5, r0, %2 \n\t" \
+ "addk r6, r0, %3 \n\t" \
+ "addk r7, r0, %4 \n\t" \
+ "addk r8, r0, %5 \n\t" \
+ "addk r9, r0, %6 \n\t" \
+ "addk r10, r0, %7 \n\t" \
+ "addik r12, r0, %1 \n\t" \
+ "brki r14, 0x8 \n\t" \
+ "addk %0, r3, r0 \n\t" \
+ : "=r" (__ret) \
+ : "i" (__NR_##name), \
+ "r" ((long)arg1), \
+ "r" ((long)arg2), \
+ "r" ((long)arg3), \
+ "r" ((long)arg4), \
+ "r" ((long)arg5), \
+ "r" ((long)arg6) \
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "r10", "r12", "r14", "cc"); \
+ __syscall_return(type, __ret); \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+extern long execve(const char *filename, char **argv, char **envp);
+
+#endif /* __KERNEL_SYSCALLS__ */
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+/* #define __ARCH_WANT_OLD_READDIR */
+/* #define __ARCH_WANT_OLD_STAT */
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#endif /* _ASM_UNISTD_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 52/52] [microblaze] setup.h string.h thread_info.h
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (41 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 51/52] [microblaze] fcntl.h sockios.h ucontext.h unistd.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 03/52] [microblaze] Cpuinfo handling monstr
` (8 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/asm-microblaze/setup.h | 36 ++++++++
include/asm-microblaze/string.h | 22 +++++
include/asm-microblaze/thread_info.h | 156 ++++++++++++++++++++++++++++++++++
3 files changed, 214 insertions(+), 0 deletions(-)
create mode 100644 include/asm-microblaze/setup.h
create mode 100644 include/asm-microblaze/string.h
create mode 100644 include/asm-microblaze/thread_info.h
diff --git a/include/asm-microblaze/setup.h b/include/asm-microblaze/setup.h
new file mode 100644
index 0000000..d8ea68e
--- /dev/null
+++ b/include/asm-microblaze/setup.h
@@ -0,0 +1,36 @@
+/*
+ * include/asm-microblaze/setup.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+#include <linux/init.h>
+
+#define COMMAND_LINE_SIZE 256
+
+int __init setup_early_printk(char *opt);
+void early_printk(const char *fmt, ...);
+void heartbeat(void);
+
+void system_timer_init(void);
+unsigned long do_gettimeoffset(void);
+void time_init(void);
+unsigned long long sched_clock(void);
+
+void __init setup_memory(void);
+void __init machine_early_init(const char *cmdline, unsigned int ram,
+ unsigned int fdt);
+
+void machine_restart(char *cmd);
+void machine_shutdown(void);
+void machine_halt(void);
+void machine_power_off(void);
+
+#endif /* _ASM_SETUP_H */
diff --git a/include/asm-microblaze/string.h b/include/asm-microblaze/string.h
new file mode 100644
index 0000000..6cd17e2
--- /dev/null
+++ b/include/asm-microblaze/string.h
@@ -0,0 +1,22 @@
+/*
+ * include/asm-microblaze/string.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_STRING_H
+#define _ASM_STRING_H
+
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#endif /* _ASM_STRING_H */
diff --git a/include/asm-microblaze/thread_info.h b/include/asm-microblaze/thread_info.h
new file mode 100644
index 0000000..dbbdeef
--- /dev/null
+++ b/include/asm-microblaze/thread_info.h
@@ -0,0 +1,156 @@
+/*
+ * include/asm-microblaze/thread_info.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * FIXME -- need review
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+/* we have 8k stack */
+#define THREAD_SHIFT 13
+#define THREAD_SIZE (1 << THREAD_SHIFT)
+
+#ifndef __ASSEMBLY__
+# include <asm/processor.h>
+# include <asm/segment.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ * must also be changed
+ */
+
+struct cpu_context {
+ __u32 sp;
+ __u32 r2;
+ /* dedicated registers */
+ __u32 r13;
+ __u32 r14;
+ __u32 r15;
+ __u32 r16;
+ __u32 r17;
+ __u32 r18;
+ /* non-volatile registers */
+ __u32 r19;
+ __u32 r20;
+ __u32 r21;
+ __u32 r22;
+ __u32 r23;
+ __u32 r24;
+ __u32 r25;
+ __u32 r26;
+ __u32 r27;
+ __u32 r28;
+ __u32 r29;
+ __u32 r30;
+ /* special purpose registers */
+ __u32 msr;
+ __u32 ear;
+ __u32 esr;
+ __u32 fsr;
+};
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ unsigned long status; /* thread-synchronous flags */
+ __u32 cpu; /* current CPU */
+ __s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
+ mm_segment_t addr_limit; /* thread address space */
+ struct restart_block restart_block;
+
+ struct cpu_context cpu_context;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = 1, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+ register unsigned long sp asm("r1");
+
+ return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
+}
+
+/* thread information allocation */
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may
+ * need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+/* restore singlestep on return to user mode */
+#define TIF_SINGLESTEP 4
+#define TIF_IRET 5 /* return with iret */
+#define TIF_MEMDIE 6
+/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG 16
+
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+#define _TIF_IRET (1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK 0x0000FFFE
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK 0x0000FFFF
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+/* FPU was used by this task this quantum (SMP) */
+#define TS_USEDFPU 0x0001
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_THREAD_INFO_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 03/52] [microblaze] Cpuinfo handling
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (42 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 52/52] [microblaze] setup.h string.h thread_info.h monstr
@ 2008-01-24 15:03 ` monstr
2008-01-27 12:55 ` Jan Engelhardt
2008-01-24 15:03 ` [PATCH 04/52] [microblaze] Open firmware files monstr
` (7 subsequent siblings)
51 siblings, 1 reply; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, microblaze
From: microblaze <microblaze@localhost.localdomain>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c | 83 +++++++++++++++++
arch/microblaze/kernel/cpu/cpuinfo-static.c | 123 +++++++++++++++++++++++++
arch/microblaze/kernel/cpu/cpuinfo.c | 93 +++++++++++++++++++
include/asm-microblaze/cpuinfo.h | 114 +++++++++++++++++++++++
4 files changed, 413 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
create mode 100644 arch/microblaze/kernel/cpu/cpuinfo-static.c
create mode 100644 arch/microblaze/kernel/cpu/cpuinfo.c
create mode 100644 include/asm-microblaze/cpuinfo.h
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
new file mode 100644
index 0000000..ea5f958
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -0,0 +1,83 @@
+/*
+ * arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+ *
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * (c) 2007 John Williams <john.williams@petalogix.com>
+ * (c) 2007 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/autoconf.h>
+#include <asm/pvr.h>
+#include <asm/cpuinfo.h>
+
+/*
+ * Helper macro to map between fields in our struct cpuinfo, and
+ * the PVR macros in pvr.h.
+ */
+
+#define CI(c, p) ci->c = PVR_##p(pvr)
+
+void set_cpuinfo_pvr_full(struct cpuinfo *ci)
+{
+ struct pvr_s pvr;
+ get_pvr(&pvr);
+
+ CI(use_barrel, USE_BARREL);
+ CI(use_divider, USE_DIV);
+ CI(use_mult, USE_HW_MUL);
+ CI(use_fpu, USE_FPU);
+
+ CI(use_mul_64, USE_MUL64);
+ CI(use_msr_instr, USE_MSR_INSTR);
+ CI(use_pcmp_instr, USE_PCMP_INSTR);
+ CI(ver_code, VERSION);
+
+ CI(use_icache, USE_ICACHE);
+ CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
+ CI(icache_write, ICACHE_ALLOW_WR);
+ CI(icache_line, ICACHE_LINE_LEN);
+ CI(icache_size, ICACHE_BYTE_SIZE);
+ CI(icache_base, ICACHE_BASEADDR);
+ CI(icache_high, ICACHE_HIGHADDR);
+
+ CI(use_dcache, USE_DCACHE);
+ CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS);
+ CI(dcache_write, DCACHE_ALLOW_WR);
+ CI(dcache_line, DCACHE_LINE_LEN);
+ CI(dcache_size, DCACHE_BYTE_SIZE);
+ CI(dcache_base, DCACHE_BASEADDR);
+ CI(dcache_high, DCACHE_HIGHADDR);
+
+ CI(use_dopb, D_OPB);
+ CI(use_iopb, I_OPB);
+ CI(use_dlmb, D_LMB);
+ CI(use_ilmb, I_LMB);
+ CI(num_fsl, FSL_LINKS);
+
+ CI(irq_edge, INTERRUPT_IS_EDGE);
+ CI(irq_positive, EDGE_IS_POSITIVE);
+
+ CI(area_optimised, AREA_OPTIMISED);
+ CI(opcode_0_illegal, OPCODE_0x0_ILLEGAL);
+ CI(exc_unaligned, UNALIGNED_EXCEPTION);
+ CI(exc_ill_opcode, ILL_OPCODE_EXCEPTION);
+ CI(exc_iopb, IOPB_BUS_EXCEPTION);
+ CI(exc_dopb, DOPB_BUS_EXCEPTION);
+ CI(exc_div_zero, DIV_ZERO_EXCEPTION);
+ CI(exc_fpu, FPU_EXCEPTION);
+
+ CI(hw_debug, DEBUG_ENABLED);
+ CI(num_pc_brk, NUMBER_OF_PC_BRK);
+ CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK);
+ CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
+
+ CI(fpga_family_code, TARGET_FAMILY);
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
new file mode 100644
index 0000000..2d35ff5
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -0,0 +1,123 @@
+/*
+ * arch/microblaze/kernel/cpu/cpuinfo-static.c
+ *
+ * (c) 2007 Michal Simek <monstr@monstr.eu>
+ * (c) 2007 John Williams <john.williams@petalogix.com>
+ * (c) 2007 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/autoconf.h>
+#include <asm/cpuinfo.h>
+
+static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+
+void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
+{
+ int i;
+ struct cpuinfo cs;
+
+ memset(&cs, 0, sizeof(struct cpuinfo));
+
+ cs.use_barrel = fcpu(cpu, "xlnx,use-barrel");
+ cs.use_divider = fcpu(cpu, "xlnx,use-div");
+ cs.use_mult = fcpu(cpu, "xlnx,use-hw-mul");
+ cs.use_fpu = fcpu(cpu, "xlnx,use-fpu");
+ cs.use_mul_64 = (cs.use_mult == 2 ? 1 : 0);
+ cs.use_msr_instr = fcpu(cpu, "xlnx,use-msr-instr");
+ cs.use_pcmp_instr = fcpu(cpu, "xlnx,use-pcmp-instr");
+
+ cs.use_exception = fcpu(cpu, "xlnx,unaligned-exceptions") ||
+ fcpu(cpu, "xlnx,ill-opcode-exception") ||
+ fcpu(cpu, "xlnx,iopb-bus-exception") ||
+ fcpu(cpu, "xlnx,dopb-bus-exception") ||
+ fcpu(cpu, "xlnx,div-zero-exception") ||
+ fcpu(cpu, "xlnx,fpu-exception");
+
+ cs.exc_unaligned = fcpu(cpu, "xlnx,unaligned-exceptions");
+ cs.exc_unaligned = fcpu(cpu, "xlnx,ill-opcode-exception");
+ cs.exc_iopb = fcpu(cpu, "xlnx,iopb-bus-exception");
+ cs.exc_dopb = fcpu(cpu, "xlnx,dopb-bus-exception");
+ cs.exc_fpu = fcpu(cpu, "xlnx,fpu-exception");
+ cs.exc_div_zero = fcpu(cpu, "xlnx,div-zero-exception");
+ cs.opcode_0_illegal = fcpu(cpu, "xlnx,opcode-0x0-illegal");
+
+ cs.use_icache = fcpu(cpu, "xlnx,use-icache");
+ cs.icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits");
+ cs.icache_write = fcpu(cpu, "xlnx,allow-icache-wr");
+ cs.icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2;
+ if (!cs.icache_line) {
+ if (fcpu(cpu, "xlnx,icache-use-fsl"))
+ cs.icache_line = 4 << 2;
+ else
+ cs.icache_line = 1 << 2;
+ }
+ cs.icache_size = fcpu(cpu, "i-cache-size");
+ cs.icache_base = fcpu(cpu, "i-cache-baseaddr");
+ cs.icache_high = fcpu(cpu, "i-cache-highaddr");
+
+ cs.use_dcache = fcpu(cpu, "xlnx,use-dcache");
+ cs.dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag");
+ cs.dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr");
+ cs.dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2;
+ if (!cs.dcache_line) {
+ if (fcpu(cpu, "xlnx,dcache-use-fsl"))
+ cs.dcache_line = 4 << 2;
+ else
+ cs.dcache_line = 1 << 2;
+ }
+ cs.dcache_size = fcpu(cpu, "d-cache-size");
+ cs.dcache_base = fcpu(cpu, "d-cache-baseaddr");
+ cs.dcache_high = fcpu(cpu, "d-cache-highaddr");
+
+ cs.use_dopb = fcpu(cpu, "xlnx,d-opb");
+ cs.use_iopb = fcpu(cpu, "xlnx,i-opb");
+ cs.use_dlmb = fcpu(cpu, "xlnx,d-lmb");
+ cs.use_ilmb = fcpu(cpu, "xlnx,i-lmb");
+
+ cs.num_fsl = fcpu(cpu, "xlnx,fsl-links");
+ cs.irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge");
+ cs.irq_positive = fcpu(cpu, "xlnx,edge-is-positive");
+ cs.area_optimised = 0;
+
+ cs.hw_debug = fcpu(cpu, "xlnx,debug-enabled");
+ cs.num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk");
+ cs.num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
+ cs.num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
+
+ cs.cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+
+ cs.ver_code = 0;
+ cs.fpga_family_code = 0;
+
+ /* Do various fixups based on CPU version and FPGA family strings */
+
+ /* Resolved the CPU version code */
+ for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+ if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0)
+ cs.ver_code = cpu_ver_lookup[i].k;
+ }
+
+ /* Resolved the fpga family code */
+ for (i = 0; family_string_lookup[i].s != NULL; i++) {
+ if (strcmp(family_string_lookup[i].s, family_string) == 0)
+ cs.fpga_family_code = family_string_lookup[i].k;
+ }
+
+ /* FIXME - mb3 and spartan2 do not exist in PVR */
+ /* This is mb3 and on a non Spartan2 */
+ if (cs.ver_code == 0x20 && cs.fpga_family_code != 0xf0)
+ /* Hardware Multiplier in use */
+ cs.use_mult = 1;
+
+ /* Copy our static CPUINFO descriptor into place */
+ memcpy(ci, &cs, sizeof(struct cpuinfo));
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
new file mode 100644
index 0000000..97c3294
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -0,0 +1,93 @@
+/*
+ * arch/microblaze/kernel/cpu/cpuinfo.c
+ *
+ * (c) 2007 Michal Simek <monstr@monstr.eu>
+ * (c) 2007 John Williams <john.williams@petalogix.com>
+ * (c) 2007 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/autoconf.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+static struct cpuinfo the_cpuinfo;
+struct cpuinfo *cpuinfo = &the_cpuinfo;
+
+static struct cpu_ver_key the_cpu_ver_lookup[] = {
+ /* These key value are as per MBV field in PVR0 */
+ {"5.00.a", 0x01},
+ {"5.00.b", 0x02},
+ {"5.00.c", 0x03},
+ {"6.00.a", 0x04},
+ {"6.00.b", 0x06},
+ {"7.00.a", 0x05},
+ /* FIXME There is no keycode defined in MBV for these versions */
+ {"2.10.a", 0x10},
+ {"3.00.a", 0x20},
+ {"4.00.a", 0x30},
+ {"4.00.b", 0x40},
+ {NULL, 0},
+};
+struct cpu_ver_key *cpu_ver_lookup =
+ (struct cpu_ver_key *) the_cpu_ver_lookup;
+
+/*
+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
+ */
+static struct family_string_key the_family_string_lookup[] = {
+ {"virtex2", 0x4},
+ {"virtex2pro", 0x5},
+ {"spartan3", 0x6},
+ {"virtex4", 0x7},
+ {"virtex5", 0x8},
+ {"spartan3e", 0x9},
+ {"spartan3a", 0xa},
+ {"spartan3an", 0xb},
+ /* FIXME There is no key code defined for spartan2 */
+ {"spartan2", 0xf0},
+ {NULL, 0},
+};
+struct family_string_key *family_string_lookup =
+ (struct family_string_key *) the_family_string_lookup;
+
+void __init setup_cpuinfo(void)
+{
+ struct device_node *cpu = NULL;
+ int pvr_level = cpu_has_pvr();
+
+ cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
+ if (!cpu)
+ printk(KERN_ERR "You don't have cpu!!!\n");
+
+ printk(KERN_INFO "%s: initialising\n", __FUNCTION__);
+
+ switch (pvr_level) {
+ case 0:
+ printk(KERN_WARNING
+ "%s: No PVR support. Using static CPU info from FDT\n",
+ __FUNCTION__);
+ set_cpuinfo_static(cpuinfo, cpu);
+ break;
+#if 0
+ case 1:
+ set_cpuinfo_pvr_partial(cpuinfo);
+ break;
+#endif
+ case 2:
+ printk(KERN_INFO "%s: Using full CPU PVR support\n",
+ __FUNCTION__);
+ set_cpuinfo_pvr_full(cpuinfo);
+ cpuinfo->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+ break;
+ default:
+ WARN_ON(1);
+ set_cpuinfo_static(cpuinfo, cpu);
+ }
+}
diff --git a/include/asm-microblaze/cpuinfo.h b/include/asm-microblaze/cpuinfo.h
new file mode 100644
index 0000000..0e1621b
--- /dev/null
+++ b/include/asm-microblaze/cpuinfo.h
@@ -0,0 +1,114 @@
+/*
+ * include/asm-microblaze/cpuinfo.h
+ *
+ * Generic support for queying CPU info
+ *
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _ASM_CPUINFO_H
+#define _ASM_CPUINFO_H
+
+#include <asm/prom.h>
+
+extern unsigned long loops_per_jiffy;
+
+/* CPU Version and FPGA Family code conversion table type */
+struct cpu_ver_key {
+ char *s;
+ unsigned k;
+};
+
+struct family_string_key {
+ char *s;
+ unsigned k;
+};
+
+struct cpuinfo {
+ /* Core CPU configuration */
+ int use_barrel;
+ int use_divider;
+ int use_mult;
+ int use_fpu;
+ int use_exception;
+ int use_mul_64;
+ int use_msr_instr;
+ int use_pcmp_instr;
+
+ int ver_code;
+
+ /* CPU caches */
+ int use_icache;
+ int icache_tagbits;
+ int icache_write;
+ int icache_line;
+ int icache_size;
+ unsigned long icache_base;
+ unsigned long icache_high;
+
+ int use_dcache;
+ int dcache_tagbits;
+ int dcache_write;
+ int dcache_line;
+ int dcache_size;
+ unsigned long dcache_base;
+ unsigned long dcache_high;
+
+ /* Bus connections */
+ int use_dopb;
+ int use_iopb;
+ int use_dlmb;
+ int use_ilmb;
+ int num_fsl;
+
+ /* CPU interrupt line info */
+ int irq_edge;
+ int irq_positive;
+
+ int area_optimised;
+
+ /* HW support for CPU exceptions */
+ int opcode_0_illegal;
+ int exc_unaligned;
+ int exc_ill_opcode;
+ int exc_iopb;
+ int exc_dopb;
+ int exc_div_zero;
+ int exc_fpu;
+
+ /* HW debug support */
+ int hw_debug;
+ int num_pc_brk;
+ int num_rd_brk;
+ int num_wr_brk;
+ int cpu_clock_freq;
+
+ /* FPGA family */
+ int fpga_family_code;
+};
+
+/* Declare a global instance of the cpuinfo_ops */
+extern struct cpuinfo *cpuinfo;
+extern struct cpu_ver_key *cpu_ver_lookup;
+extern struct family_string_key *family_string_lookup;
+
+/* fwd declarations of the various CPUinfo populators */
+void setup_cpuinfo(void);
+
+void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
+void set_cpuinfo_pvr_partial(struct cpuinfo *ci);
+void set_cpuinfo_pvr_full(struct cpuinfo *ci);
+
+static inline unsigned int fcpu(struct device_node *cpu, char *n)
+{
+ int *val;
+ return ((val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0);
+}
+
+#endif /* _ASM_CPUINFO_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 03/52] [microblaze] Cpuinfo handling
2008-01-24 15:03 ` [PATCH 03/52] [microblaze] Cpuinfo handling monstr
@ 2008-01-27 12:55 ` Jan Engelhardt
0 siblings, 0 replies; 67+ messages in thread
From: Jan Engelhardt @ 2008-01-27 12:55 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, microblaze
On Jan 24 2008 16:03, monstr@monstr.eu wrote:
>+
>+static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
>+static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
>+
I have not checked - can mark these const?
>--- /dev/null
>+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
>+
>+static struct cpuinfo the_cpuinfo;
>+struct cpuinfo *cpuinfo = &the_cpuinfo;
Why is this indirection needed?
>+static struct cpu_ver_key the_cpu_ver_lookup[] = {
^const?
>+ /* These key value are as per MBV field in PVR0 */
>+ {"5.00.a", 0x01},
>+ {"5.00.b", 0x02},
>+ {"5.00.c", 0x03},
>+ {"6.00.a", 0x04},
>+ {"6.00.b", 0x06},
>+ {"7.00.a", 0x05},
>+ /* FIXME There is no keycode defined in MBV for these versions */
>+ {"2.10.a", 0x10},
>+ {"3.00.a", 0x20},
>+ {"4.00.a", 0x30},
>+ {"4.00.b", 0x40},
>+ {NULL, 0},
>+};
>+struct cpu_ver_key *cpu_ver_lookup =
>+ (struct cpu_ver_key *) the_cpu_ver_lookup;
Again an indirection. And the case, you guessed it, is redundant
(check other code too).
>+/*
>+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
>+ */
>+static struct family_string_key the_family_string_lookup[] = {
const?
>+ {"virtex2", 0x4},
>+ {"virtex2pro", 0x5},
>+ {"spartan3", 0x6},
>+ {"virtex4", 0x7},
>+ {"virtex5", 0x8},
>+ {"spartan3e", 0x9},
>+ {"spartan3a", 0xa},
>+ {"spartan3an", 0xb},
>+ /* FIXME There is no key code defined for spartan2 */
>+ {"spartan2", 0xf0},
>+ {NULL, 0},
>+};
>+struct family_string_key *family_string_lookup =
>+ (struct family_string_key *) the_family_string_lookup;
Dito.
>+#ifndef _ASM_CPUINFO_H
>+#define _ASM_CPUINFO_H
>+
>+#include <asm/prom.h>
>+
>+extern unsigned long loops_per_jiffy;
>+
>+/* CPU Version and FPGA Family code conversion table type */
>+struct cpu_ver_key {
>+ char *s;
const char *s; if you never modify s.
>+ unsigned k;
>+};
>+
>+struct family_string_key {
>+ char *s;
Dito.
>+ unsigned k;
>+};
>+
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 04/52] [microblaze] Open firmware files
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (43 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 03/52] [microblaze] Cpuinfo handling monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 05/52] [microblaze] Support for semaphores monstr
` (6 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/of_device.c | 109 +++
arch/microblaze/kernel/of_platform.c | 395 +++++++++++
arch/microblaze/kernel/prom.c | 1248 ++++++++++++++++++++++++++++++++++
arch/microblaze/kernel/prom_parse.c | 1033 ++++++++++++++++++++++++++++
include/asm-microblaze/of_device.h | 37 +
include/asm-microblaze/of_platform.h | 37 +
include/asm-microblaze/prom.h | 333 +++++++++
7 files changed, 3192 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/of_device.c
create mode 100644 arch/microblaze/kernel/of_platform.c
create mode 100644 arch/microblaze/kernel/prom.c
create mode 100644 arch/microblaze/kernel/prom_parse.c
create mode 100644 include/asm-microblaze/of_device.h
create mode 100644 include/asm-microblaze/of_platform.h
create mode 100644 include/asm-microblaze/prom.h
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
new file mode 100644
index 0000000..7697b98
--- /dev/null
+++ b/arch/microblaze/kernel/of_device.c
@@ -0,0 +1,109 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
+#include <asm/errno.h>
+#include <asm/of_device.h>
+
+ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len)
+{
+ const char *compat;
+ int cplen, i;
+ ssize_t tsize, csize, repend;
+
+ /* Name & Type */
+ csize = snprintf(str, len, "of:N%sT%s",
+ ofdev->node->name, ofdev->node->type);
+
+ /* Get compatible property if any */
+ compat = of_get_property(ofdev->node, "compatible", &cplen);
+ if (!compat)
+ return csize;
+
+ /* Find true end (we tolerate multiple \0 at the end */
+ for (i = (cplen-1); i >= 0 && !compat[i]; i--)
+ cplen--;
+ if (!cplen)
+ return csize;
+ cplen++;
+
+ /* Check space (need cplen+1 chars including final \0) */
+ tsize = csize + cplen;
+ repend = tsize;
+
+ /* @ the limit, all is already filled */
+ if (csize >= len)
+ return tsize;
+
+ /* limit compat list */
+ if (tsize >= len) {
+ cplen = len - csize - 1;
+ repend = len;
+ }
+
+ /* Copy and do char replacement */
+ memcpy(&str[csize+1], compat, cplen);
+ for (i = csize; i < repend; i++) {
+ char c = str[i];
+ if (c == '\0')
+ str[i] = 'C';
+ else if (c == ' ')
+ str[i] = '_';
+ }
+
+ return tsize;
+}
+EXPORT_SYMBOL(of_device_get_modalias);
+
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct of_device *ofdev;
+ const char *compat;
+ int seen = 0, cplen, sl;
+
+ if (!dev)
+ return -ENODEV;
+
+ ofdev = to_of_device(dev);
+
+ if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
+ return -ENOMEM;
+
+ /* Since the compatible field can contain pretty much anything
+ * it's not really legal to split it out with commas. We split it
+ * up using a number of environment variables instead. */
+
+ compat = of_get_property(ofdev->node, "compatible", &cplen);
+ while (compat && *compat && cplen > 0) {
+ if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+ return -ENOMEM;
+
+ sl = strlen(compat) + 1;
+ compat += sl;
+ cplen -= sl;
+ seen++;
+ }
+
+ if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+ return -ENOMEM;
+
+ /* modalias is trickier, we add it in 2 steps */
+ if (add_uevent_var(env, "MODALIAS="))
+ return -ENOMEM;
+ sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
+ sizeof(env->buf) - env->buflen);
+ if (sl >= (sizeof(env->buf) - env->buflen))
+ return -ENOMEM;
+ env->buflen += sl;
+
+ return 0;
+}
+EXPORT_SYMBOL(of_device_uevent);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
new file mode 100644
index 0000000..7bdd807
--- /dev/null
+++ b/arch/microblaze/kernel/of_platform.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ * and Arnd Bergmann, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+
+#include <asm/errno.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#include <asm/topology.h>
+#include <asm/pci-bridge.h>
+#include <asm/atomic.h>
+
+/*
+ * The list of OF IDs below is used for matching bus types in the
+ * system whose devices are to be exposed as of_platform_devices.
+ *
+ * This is the default list valid for most platforms. This file provides
+ * functions who can take an explicit list if necessary though
+ *
+ * The search is always performed recursively looking for children of
+ * the provided device_node and recursively if such a children matches
+ * a bus type in the list
+ */
+
+static struct of_device_id of_default_bus_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .type = "spider", },
+ { .type = "axon", },
+ { .type = "plb5", },
+ { .type = "plb4", },
+ { .type = "opb", },
+ { .type = "ebc", },
+ {},
+};
+
+static atomic_t bus_no_reg_magic;
+
+struct bus_type of_platform_bus_type = {
+ .uevent = of_device_uevent,
+};
+EXPORT_SYMBOL(of_platform_bus_type);
+
+static int __init of_bus_driver_init(void)
+{
+ return of_bus_type_init(&of_platform_bus_type, "of_platform");
+}
+
+postcore_initcall(of_bus_driver_init);
+
+int of_register_platform_driver(struct of_platform_driver *drv)
+{
+ /* initialize common driver fields */
+ drv->driver.name = drv->name;
+ drv->driver.bus = &of_platform_bus_type;
+
+ /* register with core */
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(of_register_platform_driver);
+
+void of_unregister_platform_driver(struct of_platform_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(of_unregister_platform_driver);
+
+static void of_platform_make_bus_id(struct of_device *dev)
+{
+ struct device_node *node = dev->node;
+ char *name = dev->dev.bus_id;
+ const u32 *reg;
+ u64 addr;
+ int magic;
+
+ /*
+ * If it's a DCR based device, use 'd' for native DCRs
+ * and 'D' for MMIO DCRs.
+ */
+#ifdef CONFIG_PPC_DCR
+ reg = of_get_property(node, "dcr-reg", NULL);
+ if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+ snprintf(name, BUS_ID_SIZE, "d%x.%s",
+ *reg, node->name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+ addr = of_translate_dcr_address(node, *reg, NULL);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(name, BUS_ID_SIZE,
+ "D%llx.%s", (unsigned long long)addr,
+ node->name);
+ return;
+ }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+ }
+#endif /* CONFIG_PPC_DCR */
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(node, "reg", NULL);
+ if (reg) {
+ addr = of_translate_address(node, reg);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(name, BUS_ID_SIZE,
+ "%llx.%s", (unsigned long long)addr,
+ node->name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented
+ * counter (and pray...)
+ */
+ magic = atomic_add_return(1, &bus_no_reg_magic);
+ snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
+}
+
+struct of_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
+{
+ struct of_device *dev;
+
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->node = of_node_get(np);
+ dev->dma_mask = 0xffffffffUL;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.parent = parent;
+ dev->dev.bus = &of_platform_bus_type;
+ dev->dev.release = of_release_dev;
+ dev->dev.archdata.of_node = np;
+ dev->dev.archdata.numa_node = of_node_to_nid(np);
+
+ /* We do not fill the DMA ops for platform devices by default.
+ * This is currently the responsibility of the platform code
+ * to do such, possibly using a device notifier
+ */
+
+ if (bus_id)
+ strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
+ else
+ of_platform_make_bus_id(dev);
+
+ if (of_device_register(dev) != 0) {
+ kfree(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instanciate matching busses.
+ * @bus: device node of the bus to instanciate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(struct device_node *bus,
+ struct of_device_id *matches,
+ struct device *parent)
+{
+ struct device_node *child;
+ struct of_device *dev;
+ int rc = 0;
+
+ for (child = NULL; (child = of_get_next_child(bus, child)); ) {
+ pr_debug(" create child: %s\n", child->full_name);
+ dev = of_platform_device_create(child, NULL, parent);
+ if (dev == NULL)
+ rc = -ENOMEM;
+ else if (!of_match_node(matches, child))
+ continue;
+ if (rc == 0) {
+ pr_debug(" and sub busses\n");
+ rc = of_platform_bus_create(child, matches, &dev->dev);
+ } if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+ return rc;
+}
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instanciated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+
+int of_platform_bus_probe(struct device_node *root,
+ struct of_device_id *matches,
+ struct device *parent)
+{
+ struct device_node *child;
+ struct of_device *dev;
+ int rc = 0;
+
+ if (matches == NULL)
+ matches = of_default_bus_ids;
+ if (matches == OF_NO_DEEP_PROBE)
+ return -EINVAL;
+ if (root == NULL)
+ root = of_find_node_by_path("/");
+ else
+ of_node_get(root);
+
+ pr_debug("of_platform_bus_probe()\n");
+ pr_debug(" starting at: %s\n", root->full_name);
+
+ /* Do a self check of bus type, if there's a match, create
+ * children
+ */
+ if (of_match_node(matches, root)) {
+ pr_debug(" root match, create all sub devices\n");
+ dev = of_platform_device_create(root, NULL, parent);
+ if (dev == NULL) {
+ rc = -ENOMEM;
+ goto bail;
+ }
+ pr_debug(" create all sub busses\n");
+ rc = of_platform_bus_create(root, matches, &dev->dev);
+ goto bail;
+ }
+ for (child = NULL; (child = of_get_next_child(root, child)); ) {
+ if (!of_match_node(matches, child))
+ continue;
+
+ pr_debug(" match: %s\n", child->full_name);
+ dev = of_platform_device_create(child, NULL, parent);
+ if (dev == NULL)
+ rc = -ENOMEM;
+ else
+ rc = of_platform_bus_create(child, matches, &dev->dev);
+ if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+ bail:
+ of_node_put(root);
+ return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+ return to_of_device(dev)->node == data;
+}
+
+struct of_device *of_find_device_by_node(struct device_node *np)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&of_platform_bus_type,
+ NULL, np, of_dev_node_match);
+ if (dev)
+ return to_of_device(dev);
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+static int of_dev_phandle_match(struct device *dev, void *data)
+{
+ phandle *ph = data;
+ return to_of_device(dev)->node->linux_phandle == *ph;
+}
+
+struct of_device *of_find_device_by_phandle(phandle ph)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&of_platform_bus_type,
+ NULL, &ph, of_dev_phandle_match);
+ if (dev)
+ return to_of_device(dev);
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_phandle);
+
+#ifdef CONFIG_PPC_OF_PLATFORM_PCI
+
+/* The probing of PCI controllers from of_platform is currently
+ * 64 bits only, mostly due to gratuitous differences between
+ * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
+ * lacking some bits needed here.
+ */
+
+static int __devinit of_pci_phb_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ struct pci_controller *phb;
+
+ /* Check if we can do that ... */
+ if (ppc_md.pci_setup_phb == NULL)
+ return -ENODEV;
+
+ printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);
+
+ /* Alloc and setup PHB data structure */
+ phb = pcibios_alloc_controller(dev->node);
+ if (!phb)
+ return -ENODEV;
+
+ /* Setup parent in sysfs */
+ phb->parent = &dev->dev;
+
+ /* Setup the PHB using arch provided callback */
+ if (ppc_md.pci_setup_phb(phb)) {
+ pcibios_free_controller(phb);
+ return -ENODEV;
+ }
+
+ /* Process "ranges" property */
+ pci_process_bridge_OF_ranges(phb, dev->node, 0);
+
+ /* Init pci_dn data structures */
+ pci_devs_phb_init_dynamic(phb);
+
+ /* Register devices with EEH */
+#ifdef CONFIG_EEH
+ if (dev->node->child)
+ eeh_add_device_tree_early(dev->node);
+#endif /* CONFIG_EEH */
+
+ /* Scan the bus */
+ scan_phb(phb);
+
+ /* Claim resources. This might need some rework as well depending
+ * wether we are doing probe-only or not, like assigning unassigned
+ * resources etc...
+ */
+ pcibios_claim_one_bus(phb->bus);
+
+ /* Finish EEH setup */
+#ifdef CONFIG_EEH
+ eeh_add_device_tree_late(phb->bus);
+#endif
+
+ /* Add probed PCI devices to the device model */
+ pci_bus_add_devices(phb->bus);
+
+ return 0;
+}
+
+static struct of_device_id of_pci_phb_ids[] = {
+ { .type = "pci", },
+ { .type = "pcix", },
+ { .type = "pcie", },
+ { .type = "pciex", },
+ { .type = "ht", },
+ {}
+};
+
+static struct of_platform_driver of_pci_phb_driver = {
+ .name = "of-pci",
+ .match_table = of_pci_phb_ids,
+ .probe = of_pci_phb_probe,
+};
+
+static __init int of_pci_phb_init(void)
+{
+ return of_register_platform_driver(&of_pci_phb_driver);
+}
+
+device_initcall(of_pci_phb_init);
+
+#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
new file mode 100644
index 0000000..9cd534a
--- /dev/null
+++ b/arch/microblaze/kernel/prom.c
@@ -0,0 +1,1248 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/debugfs.h>
+#include <linux/irq.h>
+
+#include <asm/prom.h>
+#include <asm/lmb.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/pci.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(KERN_ERR fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+extern char command_line[COMMAND_LINE_SIZE];
+u32 boot_cpuid;
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+#ifdef CONFIG_PPC64
+int __initdata iommu_is_off;
+int __initdata iommu_force_on;
+unsigned long tce_alloc_start, tce_alloc_end;
+#endif
+
+typedef u32 cell_t;
+
+struct boot_param_header *initial_boot_params;
+
+extern struct device_node *allnodes; /* temporary while merging */
+
+extern rwlock_t devtree_lock; /* temporary while merging */
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+ return ((char *)initial_boot_params) +
+ initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ int rc = 0;
+ int depth = -1;
+
+ do {
+ u32 tag = *((u32 *)p);
+ char *pathp;
+
+ p += 4;
+ if (tag == OF_DT_END_NODE) {
+ depth--;
+ continue;
+ }
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag == OF_DT_END)
+ break;
+ if (tag == OF_DT_PROP) {
+ u32 sz = *((u32 *)p);
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+ p += sz;
+ p = _ALIGN(p, 4);
+ continue;
+ }
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk(KERN_WARNING "Invalid tag %x scanning flattened"
+ " device tree !\n", tag);
+ return -EINVAL;
+ }
+ depth++;
+ pathp = (char *)p;
+ p = _ALIGN(p + strlen(pathp) + 1, 4);
+ if ((*pathp) == '/') {
+ char *lp, *np;
+ for (lp = NULL, np = pathp; *np; np++)
+ if ((*np) == '/')
+ lp = np+1;
+ if (lp != NULL)
+ pathp = lp;
+ }
+ rc = it(p, pathp, depth, data);
+ if (rc != 0)
+ break;
+ } while (1);
+
+ return rc;
+}
+
+unsigned long __init of_get_flat_dt_root(void)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+
+ while (*((u32 *)p) == OF_DT_NOP)
+ p += 4;
+ BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
+ p += 4;
+ return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size)
+{
+ unsigned long p = node;
+
+ do {
+ u32 tag = *((u32 *)p);
+ u32 sz, noff;
+ const char *nstr;
+
+ p += 4;
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag != OF_DT_PROP)
+ return NULL;
+
+ sz = *((u32 *)p);
+ noff = *((u32 *)(p + 4));
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+ nstr = find_flat_dt_string(noff);
+ if (nstr == NULL) {
+ printk(KERN_WARNING "Can't find property index"
+ " name !\n");
+ return NULL;
+ }
+ if (strcmp(name, nstr) == 0) {
+ if (size)
+ *size = sz;
+ return (void *)p;
+ }
+ p += sz;
+ p = _ALIGN(p, 4);
+ } while (1);
+}
+
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+ const char *cp;
+ unsigned long cplen, l;
+
+ cp = of_get_flat_dt_prop(node, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strncasecmp(cp, compat, strlen(compat)) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+ unsigned long align)
+{
+ void *res;
+
+ *mem = _ALIGN(*mem, align);
+ res = (void *)*mem;
+ *mem += size;
+
+ return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+ unsigned long *p,
+ struct device_node *dad,
+ struct device_node ***allnextpp,
+ unsigned long fpsize)
+{
+ struct device_node *np;
+ struct property *pp, **prev_pp = NULL;
+ char *pathp;
+ u32 tag;
+ unsigned int l, allocl;
+ int has_name = 0;
+ int new_format = 0;
+
+ tag = *((u32 *)(*p));
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk("Weird tag at start of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ pathp = (char *)*p;
+ l = allocl = strlen(pathp) + 1;
+ *p = _ALIGN(*p + l, 4);
+
+ /* version 0x10 has a more compact unit name here instead of the full
+ * path. we accumulate the full path size using "fpsize", we'll rebuild
+ * it later. We detect this because the first character of the name is
+ * not '/'.
+ */
+ if ((*pathp) != '/') {
+ new_format = 1;
+ if (fpsize == 0) {
+ /* root node: special case. fpsize accounts for path
+ * plus terminating zero. root node only has '/', so
+ * fpsize should be 2, but we want to avoid the first
+ * level nodes to have two '/' so we use fpsize 1 here
+ */
+ fpsize = 1;
+ allocl = 2;
+ } else {
+ /* account for '/' and path size minus terminal 0
+ * already in 'l'
+ */
+ fpsize += l;
+ allocl = fpsize;
+ }
+ }
+
+ np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+ __alignof__(struct device_node));
+ if (allnextpp) {
+ memset(np, 0, sizeof(*np));
+ np->full_name = ((char *)np) + sizeof(struct device_node);
+ if (new_format) {
+ char *p = np->full_name;
+ /* rebuild full path for new format */
+ if (dad && dad->parent) {
+ strcpy(p, dad->full_name);
+#ifdef DEBUG
+ if ((strlen(p) + l + 1) != allocl) {
+ DBG("%s: p: %d, l: %d, a: %d\n",
+ pathp, (int)strlen(p),
+ l, allocl);
+ }
+#endif
+ p += strlen(p);
+ }
+ *(p++) = '/';
+ memcpy(p, pathp, l);
+ } else
+ memcpy(np->full_name, pathp, l);
+ prev_pp = &np->properties;
+ **allnextpp = np;
+ *allnextpp = &np->allnext;
+ if (dad != NULL) {
+ np->parent = dad;
+ /* we temporarily use the next field as `last_child'*/
+ if (dad->next == 0)
+ dad->child = np;
+ else
+ dad->next->sibling = np;
+ dad->next = np;
+ }
+ kref_init(&np->kref);
+ }
+ while (1) {
+ u32 sz, noff;
+ char *pname;
+
+ tag = *((u32 *)(*p));
+ if (tag == OF_DT_NOP) {
+ *p += 4;
+ continue;
+ }
+ if (tag != OF_DT_PROP)
+ break;
+ *p += 4;
+ sz = *((u32 *)(*p));
+ noff = *((u32 *)((*p) + 4));
+ *p += 8;
+ if (initial_boot_params->version < 0x10)
+ *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+ pname = find_flat_dt_string(noff);
+ if (pname == NULL) {
+ printk(KERN_INFO
+ "Can't find property name in list !\n");
+ break;
+ }
+ if (strcmp(pname, "name") == 0)
+ has_name = 1;
+ l = strlen(pname) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+ __alignof__(struct property));
+ if (allnextpp) {
+ if (strcmp(pname, "linux,phandle") == 0) {
+ np->node = *((u32 *)*p);
+ if (np->linux_phandle == 0)
+ np->linux_phandle = np->node;
+ }
+ if (strcmp(pname, "ibm,phandle") == 0)
+ np->linux_phandle = *((u32 *)*p);
+ pp->name = pname;
+ pp->length = sz;
+ pp->value = (void *)*p;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ }
+ *p = _ALIGN((*p) + sz, 4);
+ }
+ /* with version 0x10 we may not have the name property, recreate
+ * it here from the unit name if absent
+ */
+ if (!has_name) {
+ char *p = pathp, *ps = pathp, *pa = NULL;
+ int sz;
+
+ while (*p) {
+ if ((*p) == '@')
+ pa = p;
+ if ((*p) == '/')
+ ps = p + 1;
+ p++;
+ }
+ if (pa < ps)
+ pa = p;
+ sz = (pa - ps) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+ __alignof__(struct property));
+ if (allnextpp) {
+ pp->name = "name";
+ pp->length = sz;
+ pp->value = pp + 1;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ memcpy(pp->value, ps, sz - 1);
+ ((char *)pp->value)[sz - 1] = 0;
+ DBG("fixed up name for %s -> %s\n", pathp,
+ (char *)pp->value);
+ }
+ }
+ if (allnextpp) {
+ *prev_pp = NULL;
+ np->name = of_get_property(np, "name", NULL);
+ np->type = of_get_property(np, "device_type", NULL);
+
+ if (!np->name)
+ np->name = "<NULL>";
+ if (!np->type)
+ np->type = "<NULL>";
+ }
+ while (tag == OF_DT_BEGIN_NODE) {
+ mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+ tag = *((u32 *)(*p));
+ }
+ if (tag != OF_DT_END_NODE) {
+ printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ return mem;
+}
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+ unsigned long start, mem, size;
+ struct device_node **allnextp = &allnodes;
+
+ DBG(" -> unflatten_device_tree()\n");
+
+ /* First pass, scan for size */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+ size = (size | 3) + 1;
+
+ DBG(" size is %lx, allocating...\n", size);
+
+ /* Allocate memory for the expanded device tree */
+ mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+ mem = (unsigned long) __va(mem);
+
+ ((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+ DBG(" unflattening %lx...\n", mem);
+
+ /* Second pass, do actual unflattening */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+ if (*((u32 *)start) != OF_DT_END)
+ printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
+ *((u32 *)start));
+ if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+ printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+ ((u32 *)mem)[size / 4]);
+ *allnextp = NULL;
+
+ /* Get pointer to OF "/chosen" node for use everywhere */
+ of_chosen = of_find_node_by_path("/chosen");
+ if (of_chosen == NULL)
+ of_chosen = of_find_node_by_path("/chosen@0");
+
+ DBG(" <- unflatten_device_tree()\n");
+}
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ static int logical_cpuid;
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const u32 *intserv;
+ int i, nthreads;
+ unsigned long len;
+ int found = 0;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ /* Get physical cpuid */
+ intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
+ if (intserv) {
+ nthreads = len / sizeof(int);
+ } else {
+ intserv = of_get_flat_dt_prop(node, "reg", NULL);
+ nthreads = 1;
+ }
+
+ /*
+ * Now see if any of these threads match our boot cpu.
+ * NOTE: This must match the parsing done in smp_setup_cpu_maps.
+ */
+ for (i = 0; i < nthreads; i++) {
+ /*
+ * version 2 of the kexec param format adds the phys cpuid of
+ * booted proc.
+ */
+ if (initial_boot_params && initial_boot_params->version >= 2) {
+ if (intserv[i] ==
+ initial_boot_params->boot_cpuid_phys) {
+ found = 1;
+ break;
+ }
+ } else {
+ /*
+ * Check if it's the boot-cpu, set it's hw index now,
+ * unfortunately this format did not support booting
+ * off secondary threads.
+ */
+ if (of_get_flat_dt_prop(node,
+ "linux,boot-cpu", NULL) != NULL) {
+ found = 1;
+ break;
+ }
+ }
+
+#ifdef CONFIG_SMP
+ /* logical cpu id is always 0 on UP kernels */
+ logical_cpuid++;
+#endif
+ }
+
+ if (found) {
+ DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
+ intserv[i]);
+ boot_cpuid = logical_cpuid;
+ }
+
+#ifdef CONFIG_PPC_PSERIES
+ if (nthreads > 1)
+ cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
+ else
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+ unsigned long l;
+ u32 *prop;
+
+ DBG("Looking for initrd properties... ");
+
+ prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
+ if (prop) {
+ initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
+
+ prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
+ if (prop) {
+ initrd_end = (unsigned long)
+ __va(of_read_ulong(prop, l/4));
+ initrd_below_start_ok = 1;
+ } else {
+ initrd_start = 0;
+ }
+ }
+
+ DBG("initrd_start=0x%lx initrd_end=0x%lx\n", initrd_start, initrd_end);
+}
+#else
+static inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long l;
+ char *p;
+
+ DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+ if (depth != 1 ||
+ (strcmp(uname, "chosen") != 0 &&
+ strcmp(uname, "chosen@0") != 0))
+ return 0;
+
+#ifdef CONFIG_PPC64
+ /* check if iommu is forced on or off */
+ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
+ iommu_is_off = 1;
+ if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
+ iommu_force_on = 1;
+#endif
+
+#ifdef CONFIG_PPC64
+ lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+ if (lprop)
+ tce_alloc_start = *lprop;
+ lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+ if (lprop)
+ tce_alloc_end = *lprop;
+#endif
+
+#ifdef CONFIG_KEXEC
+ lprop = (u64 *)of_get_flat_dt_prop(node,
+ "linux,crashkernel-base", NULL);
+ if (lprop)
+ crashk_res.start = *lprop;
+
+ lprop = (u64 *)of_get_flat_dt_prop(node,
+ "linux,crashkernel-size", NULL);
+ if (lprop)
+ crashk_res.end = crashk_res.start + *lprop - 1;
+#endif
+
+ early_init_dt_check_for_initrd(node);
+
+ /* Retreive command line */
+ p = of_get_flat_dt_prop(node, "bootargs", &l);
+ if (p != NULL && l > 0)
+ strlcpy(command_line, p, min((int)l, COMMAND_LINE_SIZE));
+
+#ifdef CONFIG_CMDLINE
+ if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+ strlcpy(command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+ DBG("Command line is: %s\n", command_line);
+
+ /* break now */
+ return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+
+ if (depth != 0)
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+ dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+ DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+ prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+ dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+ DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+ /* break now */
+ return 1;
+}
+
+static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+
+ *cellp = p + s;
+ return of_read_ulong(p, s);
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Interpret the ibm,dynamic-memory property in the
+ * /ibm,dynamic-reconfiguration-memory node.
+ * This contains a list of memory blocks along with NUMA affinity
+ * information.
+ */
+static int __init early_init_dt_scan_drconf_memory(unsigned long node)
+{
+ cell_t *dm, *ls;
+ unsigned long l, n;
+ unsigned long base, size, lmb_size, flags;
+
+ ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
+ if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
+ return 0;
+ lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls);
+
+ dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l);
+ if (dm == NULL || l < sizeof(cell_t))
+ return 0;
+
+ n = *dm++; /* number of entries */
+ if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
+ return 0;
+
+ for (; n != 0; --n) {
+ base = dt_mem_next_cell(dt_root_addr_cells, &dm);
+ flags = dm[3];
+ /* skip DRC index, pad, assoc. list index, flags */
+ dm += 4;
+ /* skip this block if the reserved bit is set in flags (0x80)
+ or if the block is not assigned to this partition (0x8) */
+ if ((flags & 0x80) || !(flags & 0x8))
+ continue;
+ size = lmb_size;
+ if (iommu_is_off) {
+ if (base >= 0x80000000ul)
+ continue;
+ if ((base + size) > 0x80000000ul)
+ size = 0x80000000ul - base;
+ }
+ lmb_add(base, size);
+ }
+ lmb_dump_all();
+ return 0;
+}
+#else
+#define early_init_dt_scan_drconf_memory(node) 0
+#endif /* CONFIG_PPC_PSERIES */
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ cell_t *reg, *endp;
+ unsigned long l;
+
+ /* Look for the ibm,dynamic-reconfiguration-memory node */
+ if (depth == 1 &&
+ strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
+ return early_init_dt_scan_drconf_memory(node);
+
+ /* We are scanning "memory" nodes only */
+ if (type == NULL) {
+ /*
+ * The longtrail doesn't have a device_type on the
+ * /memory node, so look for the node called /memory@0.
+ */
+ if (depth != 1 || strcmp(uname, "memory@0") != 0)
+ return 0;
+ } else if (strcmp(type, "memory") != 0)
+ return 0;
+
+ reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+ if (reg == NULL)
+ reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(cell_t));
+
+ DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
+ uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ unsigned long base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, ®);
+ size = dt_mem_next_cell(dt_root_size_cells, ®);
+
+ if (size == 0)
+ continue;
+ DBG(" - %lx , %lx\n", base, size);
+#ifdef CONFIG_PPC64
+ if (iommu_is_off) {
+ if (base >= 0x80000000ul)
+ continue;
+ if ((base + size) > 0x80000000ul)
+ size = 0x80000000ul - base;
+ }
+#endif
+ lmb_add(base, size);
+ }
+ return 0;
+}
+
+void __init early_init_devtree(void *params)
+{
+ DBG(" -> early_init_devtree(%p)\n", params);
+
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+#ifdef CONFIG_PPC_RTAS
+ /* Some machines might need RTAS info for debugging, grab it now. */
+ of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
+#endif
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, TCE reserve, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+ /* Scan memory nodes and rebuild LMBs */
+ lmb_init();
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+ /* Save command line for /proc/cmdline and then parse parameters */
+ strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+ parse_early_param();
+
+ lmb_analyze();
+
+ DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+
+ DBG("Scanning CPUs ...\n");
+
+ /* Retreive CPU related informations from the flat tree
+ * (altivec support, boot CPU ID, ...)
+ */
+ of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+ DBG(" <- early_init_devtree()\n");
+}
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+ struct device_node *root;
+ int rc = 0;
+
+ root = of_find_node_by_path("/");
+ if (root) {
+ rc = of_device_is_compatible(root, compat);
+ of_node_put(root);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done. The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ for (np = allnodes; np != 0; np = np->allnext)
+ if (np->linux_phandle == handle)
+ break;
+ of_node_get(np);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev: Previous node or NULL to start iteration
+ * of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = prev ? prev->allnext : allnodes;
+ for (; np != 0; np = np->allnext)
+ if (of_node_get(np))
+ break;
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
+/**
+ * of_node_get - Increment refcount of a node
+ * @node: Node to inc refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ * Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+ if (node)
+ kref_get(&node->kref);
+ return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node *kref_to_device_node(struct kref *kref)
+{
+ return container_of(kref, struct device_node, kref);
+}
+
+/**
+ * of_node_release - release a dynamically allocated node
+ * @kref: kref element of the node to be released
+ *
+ * In of_node_put() this function is passed to kref_put()
+ * as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+ struct device_node *node = kref_to_device_node(kref);
+ struct property *prop = node->properties;
+
+ /* We should never be releasing nodes that haven't been detached. */
+ if (!of_node_check_flag(node, OF_DETACHED)) {
+ printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
+ node->full_name);
+ dump_stack();
+ kref_init(&node->kref);
+ return;
+ }
+
+ if (!of_node_check_flag(node, OF_DYNAMIC))
+ return;
+
+ while (prop) {
+ struct property *next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ prop = next;
+
+ if (!prop) {
+ prop = node->deadprops;
+ node->deadprops = NULL;
+ }
+ }
+ kfree(node->full_name);
+ kfree(node->data);
+ kfree(node);
+}
+
+/**
+ * of_node_put - Decrement refcount of a node
+ * @node: Node to dec refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+ if (node)
+ kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+ write_lock(&devtree_lock);
+ np->sibling = np->parent->child;
+ np->allnext = allnodes;
+ np->parent->child = np;
+ allnodes = np;
+ write_unlock(&devtree_lock);
+}
+
+/*
+ * "Unplug" a node from the device tree. The caller must hold
+ * a reference to the node. The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(struct device_node *np)
+{
+ struct device_node *parent;
+
+ write_lock(&devtree_lock);
+
+ parent = np->parent;
+ if (!parent)
+ goto out_unlock;
+
+ if (allnodes == np)
+ allnodes = np->allnext;
+ else {
+ struct device_node *prev;
+ for (prev = allnodes;
+ prev->allnext != np;
+ prev = prev->allnext)
+ ;
+ prev->allnext = np->allnext;
+ }
+
+ if (parent->child == np)
+ parent->child = np->sibling;
+ else {
+ struct device_node *prevsib;
+ for (prevsib = np->parent->child;
+ prevsib->sibling != np;
+ prevsib = prevsib->sibling)
+ ;
+ prevsib->sibling = np->sibling;
+ }
+
+ of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
+ write_unlock(&devtree_lock);
+}
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Fix up the uninitialized fields in a new device node:
+ * name, type and pci-specific fields
+ */
+
+static int of_finish_dynamic_node(struct device_node *node)
+{
+ struct device_node *parent = of_get_parent(node);
+ int err = 0;
+ const phandle *ibm_phandle;
+
+ node->name = of_get_property(node, "name", NULL);
+ node->type = of_get_property(node, "device_type", NULL);
+
+ if (!node->name)
+ node->name = "<NULL>";
+ if (!node->type)
+ node->type = "<NULL>";
+
+ if (!parent) {
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* We don't support that function on PowerMac, at least
+ * not yet
+ */
+ if (machine_is(powermac))
+ return -ENODEV;
+
+ /* fix up new node's linux_phandle field */
+ if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL)))
+ node->linux_phandle = *ibm_phandle;
+
+out:
+ of_node_put(parent);
+ return err;
+}
+
+static int prom_reconfig_notifier(struct notifier_block *nb,
+ unsigned long action, void *node)
+{
+ int err;
+
+ switch (action) {
+ case PSERIES_RECONFIG_ADD:
+ err = of_finish_dynamic_node(node);
+ if (err < 0) {
+ printk(KERN_ERR "finish_node returned %d\n", err);
+ err = NOTIFY_BAD;
+ }
+ break;
+ default:
+ err = NOTIFY_DONE;
+ break;
+ }
+ return err;
+}
+
+static struct notifier_block prom_reconfig_nb = {
+ .notifier_call = prom_reconfig_notifier,
+ .priority = 10, /* This one needs to run first */
+};
+
+static int __init prom_reconfig_setup(void)
+{
+ return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
+}
+__initcall(prom_reconfig_setup);
+#endif
+
+/*
+ * Add a property to a node
+ */
+int prom_add_property(struct device_node *np, struct property *prop)
+{
+ struct property **next;
+
+ prop->next = NULL;
+ write_lock(&devtree_lock);
+ next = &np->properties;
+ while (*next) {
+ if (strcmp(prop->name, (*next)->name) == 0) {
+ /* duplicate ! don't insert it */
+ write_unlock(&devtree_lock);
+ return -1;
+ }
+ next = &(*next)->next;
+ }
+ *next = prop;
+ write_unlock(&devtree_lock);
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/*
+ * Remove a property from a node. Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property. Instead we just move the property
+ * to the "dead properties" list, so it won't be found any more.
+ */
+int prom_remove_property(struct device_node *np, struct property *prop)
+{
+ struct property **next;
+ int found = 0;
+
+ write_lock(&devtree_lock);
+ next = &np->properties;
+ while (*next) {
+ if (*next == prop) {
+ /* found the node */
+ *next = prop->next;
+ prop->next = np->deadprops;
+ np->deadprops = prop;
+ found = 1;
+ break;
+ }
+ next = &(*next)->next;
+ }
+ write_unlock(&devtree_lock);
+
+ if (!found)
+ return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to remove the proc node as well */
+ if (np->pde)
+ proc_device_tree_remove_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/*
+ * Update a property in a node. Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property. Instead we just move the property
+ * to the "dead properties" list, and add the new property to the
+ * property list
+ */
+int prom_update_property(struct device_node *np,
+ struct property *newprop,
+ struct property *oldprop)
+{
+ struct property **next;
+ int found = 0;
+
+ write_lock(&devtree_lock);
+ next = &np->properties;
+ while (*next) {
+ if (*next == oldprop) {
+ /* found the node */
+ newprop->next = oldprop->next;
+ *next = newprop;
+ oldprop->next = np->deadprops;
+ np->deadprops = oldprop;
+ found = 1;
+ break;
+ }
+ next = &(*next)->next;
+ }
+ write_unlock(&devtree_lock);
+
+ if (!found)
+ return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_update_prop(np->pde, newprop, oldprop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/* Find the device node for a given logical cpu number, also returns the cpu
+ * local thread number (index in ibm,interrupt-server#s) if relevant and
+ * asked for (non NULL)
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+ int hardid;
+ struct device_node *np;
+
+ hardid = boot_cpuid; /* get_hard_smp_processor_id(cpu);*/
+
+ for_each_node_by_type(np, "cpu") {
+ const u32 *intserv;
+ unsigned int plen, t;
+
+ /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
+ * fallback to "reg" property and assume no threads
+ */
+ intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
+ &plen);
+ if (intserv == NULL) {
+ const u32 *reg = of_get_property(np, "reg", NULL);
+ if (reg == NULL)
+ continue;
+ if (*reg == hardid) {
+ if (thread)
+ *thread = 0;
+ return np;
+ }
+ } else {
+ plen /= sizeof(u32);
+ for (t = 0; t < plen; t++) {
+ if (hardid == intserv[t]) {
+ if (thread)
+ *thread = t;
+ return np;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_node);
+
+#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+ struct dentry *d;
+
+ flat_dt_blob.data = initial_boot_params;
+ flat_dt_blob.size = initial_boot_params->totalsize;
+
+ d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+ powerpc_debugfs_root, &flat_dt_blob);
+ if (!d)
+ return 1;
+
+ return 0;
+}
+__initcall(export_flat_device_tree);
+#endif
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
new file mode 100644
index 0000000..eeb96dd
--- /dev/null
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -0,0 +1,1033 @@
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci_regs.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/etherdevice.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#ifdef CONFIG_PPC64
+#define PRu64 "%lx"
+#else
+#define PRu64 "%llx"
+#endif
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS 4
+#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+ (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev,
+ const u32 *addrp, u64 size, unsigned int flags,
+ struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+ printk(KERN_INFO "%s", s);
+ while (na--)
+ printk(KERN_INFO " %08x", *(addr++));
+ printk(KERN_INFO "\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+ const char *name;
+ const char *addresses;
+ int (*match)(struct device_node *parent);
+ void (*count_cells)(struct device_node *child,
+ int *addrc, int *sizec);
+ u64 (*map)(u32 *addr, const u32 *range,
+ int na, int ns, int pna);
+ int (*translate)(u32 *addr, u64 offset, int na);
+ unsigned int (*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+ int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = of_read_number(range, na);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr, na);
+
+ pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
+ cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+ u64 a = of_read_number(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = a >> 32;
+ addr[na - 1] = a & 0xffffffffu;
+
+ return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+ return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+ /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+ return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 3;
+ if (sizec)
+ *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x03000000)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_number(range + 1, na - 1);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr + 1, na - 1);
+
+ pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+ return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+ unsigned int flags = 0;
+ u32 w = addr[0];
+
+ switch ((w >> 24) & 0x03) {
+ case 0x01:
+ flags |= IORESOURCE_IO;
+ break;
+ case 0x02: /* 32 bits */
+ case 0x03: /* 64 bits */
+ flags |= IORESOURCE_MEM;
+ break;
+ }
+ if (w & 0x40000000)
+ flags |= IORESOURCE_PREFETCH;
+ return flags;
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+ unsigned int *flags)
+{
+ const u32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ if (strcmp(bus->name, "pci")) {
+ of_node_put(parent);
+ return NULL;
+ }
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_COUNTS(na, ns))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+ struct resource *r)
+{
+ const u32 *addrp;
+ u64 size;
+ unsigned int flags;
+
+ addrp = of_get_pci_address(dev, bar, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+ return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+ return (((pin - 1) + slot) % 4) + 1;
+}
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+ struct device_node *dn, *ppnode;
+ struct pci_dev *ppdev;
+ u32 lspec;
+ u32 laddr[3];
+ u8 pin;
+ int rc;
+
+ /* Check if we have a device node, if yes, fallback to standard OF
+ * parsing
+ */
+ dn = pci_device_to_OF_node(pdev);
+ if (dn)
+ return of_irq_map_one(dn, 0, out_irq);
+
+ /* Ok, we don't, time to have fun. Let's start by building up an
+ * interrupt spec. we assume #interrupt-cells is 1, which is standard
+ * for PCI. If you do different, then don't use that routine.
+ */
+ rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+ if (rc != 0)
+ return rc;
+ /* No pin, exit */
+ if (pin == 0)
+ return -ENODEV;
+
+ /* Now we walk up the PCI tree */
+ lspec = pin;
+ for (;;) {
+ /* Get the pci_dev of our parent */
+ ppdev = pdev->bus->self;
+
+ /* Ouch, it's a host bridge... */
+ if (ppdev == NULL) {
+#ifdef CONFIG_PPC64
+ ppnode = pci_bus_to_OF_node(pdev->bus);
+#else
+ struct pci_controller *host;
+ host = pci_bus_to_host(pdev->bus);
+ ppnode = host ? host->arch_data : NULL;
+#endif
+ /* No node for host bridge ? give up */
+ if (ppnode == NULL)
+ return -EINVAL;
+ } else
+ /* We found a P2P bridge, check if it has a node */
+ ppnode = pci_device_to_OF_node(ppdev);
+
+ /* Ok, we have found a parent with a device-node, hand over to
+ * the OF parsing code.
+ * We build a unit address from the linux device to be used for
+ * resolution. Note that we use the linux bus number which may
+ * not match your firmware bus numbering.
+ * Fortunately, in most cases, interrupt-map-mask doesn't
+ * include the bus number as part of the matching.
+ * You should still be careful about that though if you intend
+ * to rely on this function (you ship a firmware that doesn't
+ * create device nodes for all PCI devices).
+ */
+ if (ppnode)
+ break;
+
+ /* We can only get here if we hit a P2P bridge with no node,
+ * let's do standard swizzling and try again
+ */
+ lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
+ pdev = ppdev;
+ }
+
+ laddr[0] = (pdev->bus->number << 16)
+ | (pdev->devfn << 8);
+ laddr[1] = laddr[2] = 0;
+ return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+ return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 2;
+ if (sizec)
+ *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x00000001)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_number(range + 1, na - 1);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr + 1, na - 1);
+
+ pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+ return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+ unsigned int flags = 0;
+ u32 w = addr[0];
+
+ if (w & 1)
+ flags |= IORESOURCE_IO;
+ else
+ flags |= IORESOURCE_MEM;
+ return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+ /* PCI */
+ {
+ .name = "pci",
+ .addresses = "assigned-addresses",
+ .match = of_bus_pci_match,
+ .count_cells = of_bus_pci_count_cells,
+ .map = of_bus_pci_map,
+ .translate = of_bus_pci_translate,
+ .get_flags = of_bus_pci_get_flags,
+ },
+#endif /* CONFIG_PCI */
+ /* ISA */
+ {
+ .name = "isa",
+ .addresses = "reg",
+ .match = of_bus_isa_match,
+ .count_cells = of_bus_isa_count_cells,
+ .map = of_bus_isa_map,
+ .translate = of_bus_isa_translate,
+ .get_flags = of_bus_isa_get_flags,
+ },
+ /* Default */
+ {
+ .name = "default",
+ .addresses = "reg",
+ .match = NULL,
+ .count_cells = of_bus_default_count_cells,
+ .map = of_bus_default_map,
+ .translate = of_bus_default_translate,
+ .get_flags = of_bus_default_get_flags,
+ },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+ if (!of_busses[i].match || of_busses[i].match(np))
+ return &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ struct of_bus *pbus, u32 *addr,
+ int na, int ns, int pna)
+{
+ const u32 *ranges;
+ unsigned int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /* Normally, an absence of a "ranges" property means we are
+ * crossing a non-translatable boundary, and thus the addresses
+ * below the current not cannot be converted to CPU physical ones.
+ * Unfortunately, while this is very clear in the spec, it's not
+ * what Apple understood, and they do have things like /uni-n or
+ * /ht nodes with no "ranges" property and a lot of perfectly
+ * useable mapped devices below them. Thus we treat the absence of
+ * "ranges" as equivalent to an empty "ranges" property which means
+ * a 1:1 translation at that level. It's up to the caller not to try
+ * to translate addresses that aren't supposed to be translated in
+ * the first place. --BenH.
+ */
+ ranges = of_get_property(parent, "ranges", (int *) &rlen);
+ if (ranges == NULL || rlen == 0) {
+ offset = of_read_number(addr, na);
+ memset(addr, 0, pna * 4);
+ pr_debug("OF: no ranges, 1:1 translation\n");
+ goto finish;
+ }
+
+ pr_debug("OF: walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ pr_debug("OF: not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("OF: parent translation for:", addr, pna);
+ pr_debug("OF: with offset: "PRu64"\n", offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ u32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+ /* Increase refcount at current level */
+ of_node_get(dev);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ goto bail;
+ bus = of_match_bus(parent);
+
+ /* Cound address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ goto bail;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+ bus->name, na, ns, parent->full_name);
+ of_dump_addr("OF: translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ of_node_put(dev);
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ pr_debug("OF: reached root node\n");
+ result = of_read_number(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ break;
+ }
+
+ pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+ pbus->name, pna, pns, parent->full_name);
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("OF: one level translation:", addr, na);
+ }
+ bail:
+ of_node_put(parent);
+ of_node_put(dev);
+
+ return result;
+}
+EXPORT_SYMBOL(of_translate_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ unsigned int *flags)
+{
+ const u32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_COUNTS(na, ns))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, (int *) &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+ u64 size, unsigned int flags,
+ struct resource *r)
+{
+ u64 taddr;
+
+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ return -EINVAL;
+ taddr = of_translate_address(dev, addrp);
+ if (taddr == OF_BAD_ADDR)
+ return -EINVAL;
+ memset(r, 0, sizeof(struct resource));
+ if (flags & IORESOURCE_IO) {
+ unsigned long port;
+ port = -1; /* pci_address_to_pio(taddr); */
+ if (port == (unsigned long)-1)
+ return -EINVAL;
+ r->start = port;
+ r->end = port + size - 1;
+ } else {
+ r->start = taddr;
+ r->end = taddr + size - 1;
+ }
+ r->flags = flags;
+ r->name = dev->name;
+ return 0;
+}
+
+int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ const u32 *addrp;
+ u64 size;
+ unsigned int flags;
+
+ addrp = of_get_address(dev, index, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+ return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+ unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+ const u32 *dma_window;
+ u32 cells;
+ const unsigned char *prop;
+
+ dma_window = dma_window_prop;
+
+ /* busno is always one cell */
+ *busno = *(dma_window++);
+
+ prop = of_get_property(dn, "ibm,#dma-address-cells", NULL);
+ if (!prop)
+ prop = of_get_property(dn, "#address-cells", NULL);
+
+ cells = prop ? *(u32 *)prop : of_n_addr_cells(dn);
+ *phys = of_read_number(dma_window, cells);
+
+ dma_window += cells;
+
+ prop = of_get_property(dn, "ibm,#dma-size-cells", NULL);
+ cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
+ *size = of_read_number(dma_window, cells);
+}
+
+/*
+ * Interrupt remapper
+ */
+
+static unsigned int of_irq_workarounds;
+static struct device_node *of_irq_dflt_pic;
+
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+ struct device_node *p;
+ const phandle *parp;
+
+ if (!of_node_get(child))
+ return NULL;
+
+ do {
+ parp = of_get_property(child, "interrupt-parent", NULL);
+ if (parp == NULL)
+ p = of_get_parent(child);
+ else {
+ if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+ p = of_node_get(of_irq_dflt_pic);
+ else
+ p = of_find_node_by_phandle(*parp);
+ }
+ of_node_put(child);
+ child = p;
+ } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+ return p;
+}
+
+/* This doesn't need to be called if you don't have any special workaround
+ * flags to pass
+ */
+void of_irq_map_init(unsigned int flags)
+{
+ of_irq_workarounds = flags;
+
+ /* OldWorld, don't bother looking at other things */
+ if (flags & OF_IMAP_OLDWORLD_MAC)
+ return;
+
+ /* If we don't have phandles, let's try to locate a default interrupt
+ * controller (happens when booting with BootX). We do a first match
+ * here, hopefully, that only ever happens on machines with one
+ * controller.
+ */
+ if (flags & OF_IMAP_NO_PHANDLE) {
+ struct device_node *np;
+
+ for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
+ if (of_get_property(np, "interrupt-controller", NULL)
+ == NULL)
+ continue;
+ /* Skip /chosen/interrupt-controller */
+ if (strcmp(np->name, "chosen") == 0)
+ continue;
+ /* It seems like at least one person on this planet
+ * wants to use BootX on a machine with an AppleKiwi
+ * controller which happens to pretend to be an
+ * interrupt controller too.
+ */
+ if (strcmp(np->name, "AppleKiwi") == 0)
+ continue;
+ /* I think we found one ! */
+ of_irq_dflt_pic = np;
+ break;
+ }
+ }
+
+}
+
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+ const u32 *addr, struct of_irq *out_irq)
+{
+ struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+ const u32 *tmp, *imap, *imask;
+ u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ int imaplen, match, i;
+
+ pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
+ "ointsize=%d\n",
+ parent->full_name, intspec[0], intspec[1], ointsize);
+
+ ipar = of_node_get(parent);
+
+ /* First get the #interrupt-cells property of the current cursor
+ * that tells us how to interpret the passed-in intspec. If there
+ * is none, we are nice and just walk up the tree
+ */
+ do {
+ tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+ if (tmp != NULL) {
+ intsize = *tmp;
+ break;
+ }
+ tnode = ipar;
+ ipar = of_irq_find_parent(ipar);
+ of_node_put(tnode);
+ } while (ipar);
+ if (ipar == NULL) {
+ pr_debug(" -> no parent found !\n");
+ goto fail;
+ }
+
+ pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
+ ipar->full_name, intsize);
+
+ if (ointsize != intsize)
+ return -EINVAL;
+
+ /* Look for this #address-cells. We have to implement the old linux
+ * trick of looking for the parent here as some device-trees rely on it
+ */
+ old = of_node_get(ipar);
+ do {
+ tmp = of_get_property(old, "#address-cells", NULL);
+ tnode = of_get_parent(old);
+ of_node_put(old);
+ old = tnode;
+ } while (old && tmp == NULL);
+ of_node_put(old);
+ old = NULL;
+ addrsize = (tmp == NULL) ? 2 : *tmp;
+
+ pr_debug(" -> addrsize=%d\n", addrsize);
+
+ /* Now start the actual "proper" walk of the interrupt tree */
+ while (ipar != NULL) {
+ /* Now check if cursor is an interrupt-controller and if it is
+ * then we are done
+ */
+ if (of_get_property(ipar, "interrupt-controller", NULL) !=
+ NULL) {
+ pr_debug(" -> got it !\n");
+ memcpy(out_irq->specifier, intspec,
+ intsize * sizeof(u32));
+ out_irq->size = intsize;
+ out_irq->controller = ipar;
+ of_node_put(old);
+ return 0;
+ }
+
+ /* Now look for an interrupt-map */
+ imap = of_get_property(ipar, "interrupt-map", &imaplen);
+ /* No interrupt map, check for an interrupt parent */
+ if (imap == NULL) {
+ pr_debug(" -> no map, getting parent\n");
+ newpar = of_irq_find_parent(ipar);
+ goto skiplevel;
+ }
+ imaplen /= sizeof(u32);
+
+ /* Look for a mask */
+ imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+ /* If we were passed no "reg" property and we attempt to parse
+ * an interrupt-map, then #address-cells must be 0.
+ * Fail if it's not.
+ */
+ if (addr == NULL && addrsize != 0) {
+ pr_debug(" -> no reg passed in when needed !\n");
+ goto fail;
+ }
+
+ /* Parse interrupt-map */
+ match = 0;
+ while (imaplen > (addrsize + intsize + 1) && !match) {
+ /* Compare specifiers */
+ match = 1;
+ for (i = 0; i < addrsize && match; ++i) {
+ u32 mask = imask ? imask[i] : 0xffffffffu;
+ match = ((addr[i] ^ imap[i]) & mask) == 0;
+ }
+ for (; i < (addrsize + intsize) && match; ++i) {
+ u32 mask = imask ? imask[i] : 0xffffffffu;
+ match =
+ ((intspec[i-addrsize] ^ imap[i])
+ & mask) == 0;
+ }
+ imap += addrsize + intsize;
+ imaplen -= addrsize + intsize;
+
+ pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+ /* Get the interrupt parent */
+ if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+ newpar = of_node_get(of_irq_dflt_pic);
+ else
+ newpar =
+ of_find_node_by_phandle((phandle)*imap);
+ imap++;
+ --imaplen;
+
+ /* Check if not found */
+ if (newpar == NULL) {
+ pr_debug(" -> imap parent not found !\n");
+ goto fail;
+ }
+
+ /* Get #interrupt-cells and #address-cells of new
+ * parent
+ */
+ tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+ if (tmp == NULL) {
+ pr_debug(" -> parent lacks "
+ "#interrupt-cells!\n");
+ goto fail;
+ }
+ newintsize = *tmp;
+ tmp = of_get_property(newpar, "#address-cells", NULL);
+ newaddrsize = (tmp == NULL) ? 0 : *tmp;
+
+ pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+ newintsize, newaddrsize);
+
+ /* Check for malformed properties */
+ if (imaplen < (newaddrsize + newintsize))
+ goto fail;
+
+ imap += newaddrsize + newintsize;
+ imaplen -= newaddrsize + newintsize;
+
+ pr_debug(" -> imaplen=%d\n", imaplen);
+ }
+ if (!match)
+ goto fail;
+
+ of_node_put(old);
+ old = of_node_get(newpar);
+ addrsize = newaddrsize;
+ intsize = newintsize;
+ intspec = imap - intsize;
+ addr = intspec - addrsize;
+
+skiplevel:
+ /* Iterate again with new parent */
+ pr_debug(" -> new parent: %s\n",
+ newpar ? newpar->full_name : "<>");
+ of_node_put(ipar);
+ ipar = newpar;
+ newpar = NULL;
+ }
+fail:
+ of_node_put(ipar);
+ of_node_put(old);
+ of_node_put(newpar);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+int of_irq_map_one(struct device_node *device,
+ int index, struct of_irq *out_irq)
+{
+ struct device_node *p;
+ const u32 *intspec, *tmp, *addr;
+ u32 intsize, intlen;
+ int res;
+
+ pr_debug("of_irq_map_one: dev=%s, index=%d\n",
+ device->full_name, index);
+
+ /* Get the interrupts property */
+ intspec = of_get_property(device, "interrupts", (int *) &intlen);
+ if (intspec == NULL)
+ return -EINVAL;
+ intlen /= sizeof(u32);
+
+ pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+ /* Get the reg property (if any) */
+ addr = of_get_property(device, "reg", NULL);
+
+ /* Look for the interrupt parent. */
+ p = of_irq_find_parent(device);
+ if (p == NULL)
+ return -EINVAL;
+
+ /* Get size of interrupt specifier */
+ tmp = of_get_property(p, "#interrupt-cells", NULL);
+ if (tmp == NULL) {
+ of_node_put(p);
+ return -EINVAL;
+ }
+ intsize = *tmp;
+
+ pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+ /* Check index */
+ if ((index + 1) * intsize > intlen)
+ return -EINVAL;
+
+ /* Get new specifier and map it */
+ res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+ addr, out_irq);
+ of_node_put(p);
+ return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * Search the device tree for the best MAC address to use. 'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address. If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot. For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses. Some older U-Boots only initialized 'local-mac-address'. In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+const void *of_get_mac_address(struct device_node *np)
+{
+ struct property *pp;
+
+ pp = of_find_property(np, "mac-address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ pp = of_find_property(np, "local-mac-address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ pp = of_find_property(np, "address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_mac_address);
+
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+ struct of_irq out_irq;
+ int irq;
+ int res;
+
+ res = of_irq_map_one(dev, index, &out_irq);
+
+ /* Get irq for the device */
+ if (res) {
+ pr_debug("IRQ not found... code = %d", res);
+ return NO_IRQ;
+ }
+ /* Assuming single interrupt controller... */
+ irq = out_irq.specifier[0];
+
+ pr_debug("IRQ found = %d", irq);
+
+ /* Only dereference the resource if both the
+ * resource and the irq are valid. */
+ if (r && irq != NO_IRQ) {
+ r->start = r->end = irq;
+ r->flags = IORESOURCE_IRQ;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/include/asm-microblaze/of_device.h b/include/asm-microblaze/of_device.h
new file mode 100644
index 0000000..6df76b9
--- /dev/null
+++ b/include/asm-microblaze/of_device.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/of_device.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#ifndef _ASM_OF_DEVICE_H
+#define _ASM_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/of.h>
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device {
+ struct device_node *node; /* to be obsoleted */
+ u64 dma_mask; /* DMA mask */
+ struct device dev; /* Generic device interface */
+};
+
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len);
+extern int of_device_uevent(struct device *dev,
+ struct kobj_uevent_env *env);
+
+/* This is just here during the transition */
+#include <linux/of_device.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_OF_DEVICE_H */
diff --git a/include/asm-microblaze/of_platform.h b/include/asm-microblaze/of_platform.h
new file mode 100644
index 0000000..aed450f
--- /dev/null
+++ b/include/asm-microblaze/of_platform.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-microblaze/of_platform.h
+ *
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef _ASM_OF_PLATFORM_H
+#define _ASM_OF_PLATFORM_H
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+/* Platform drivers register/unregister */
+extern int of_register_platform_driver(struct of_platform_driver *drv);
+extern void of_unregister_platform_driver(struct of_platform_driver *drv);
+
+/* Platform devices and busses creation */
+extern struct of_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent);
+/* pseudo "matches" value to not do deep probe */
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+
+extern int of_platform_bus_probe(struct device_node *root,
+ struct of_device_id *matches,
+ struct device *parent);
+
+extern struct of_device *of_find_device_by_phandle(phandle ph);
+
+#endif /* _ASM_OF_PLATFORM_H */
diff --git a/include/asm-microblaze/prom.h b/include/asm-microblaze/prom.h
new file mode 100644
index 0000000..ed500ba
--- /dev/null
+++ b/include/asm-microblaze/prom.h
@@ -0,0 +1,333 @@
+/*
+ * include/asm-microblaze/prom.h
+ *
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROM_H
+#define _ASM_PROM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+
+#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
+#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
+#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size, content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+/*
+ * This is what gets passed to the kernel by prom_init or kexec
+ *
+ * The dt struct contains the device tree structure, full pathes and
+ * property contents. The dt strings contain a separate block with just
+ * the strings for the property names, and is fully page aligned and
+ * self contained in a page, so that it can be kept around by the kernel,
+ * each property name appears only once in this page (cheap compression)
+ *
+ * the mem_rsvmap contains a map of reserved ranges of physical memory,
+ * passing it here instead of in the device-tree itself greatly simplifies
+ * the job of everybody. It's just a list of u64 pairs (base/size) that
+ * ends when size is 0
+ */
+struct boot_param_header {
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+ /* version 17 fields below */
+ u32 dt_struct_size; /* size of the DT structure block */
+};
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct property {
+ char *name;
+ int length;
+ void *value;
+ struct property *next;
+};
+
+struct device_node {
+ const char *name;
+ const char *type;
+ phandle node;
+ phandle linux_phandle;
+ char *full_name;
+
+ struct property *properties;
+ struct property *deadprops; /* removed properties */
+ struct device_node *parent;
+ struct device_node *child;
+ struct device_node *sibling;
+ struct device_node *next; /* next device of same type */
+ struct device_node *allnext; /* next in list of all nodes */
+ struct proc_dir_entry *pde; /* this node's proc directory */
+ struct kref kref;
+ unsigned long _flags;
+ void *data;
+};
+
+extern struct device_node *of_chosen;
+
+static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
+{
+ return test_bit(flag, &n->_flags);
+}
+
+static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
+{
+ set_bit(flag, &n->_flags);
+}
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+static inline void set_node_proc_entry(struct device_node *dn,
+ struct proc_dir_entry *de)
+{
+ dn->pde = de;
+}
+
+extern struct device_node *of_find_all_nodes(struct device_node *prev);
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+
+/* For scanning the flat device-tree at boot time */
+extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data);
+extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size);
+extern int __init
+ of_flat_dt_is_compatible(unsigned long node, const char *name);
+extern unsigned long __init of_get_flat_dt_root(void);
+
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(struct device_node *);
+
+/* Other Prototypes */
+extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern void early_init_devtree(void *);
+#define device_is_compatible(d, c) of_device_is_compatible((d), (c))
+extern int machine_is_compatible(const char *compat);
+extern void print_properties(struct device_node *node);
+extern int prom_n_intr_cells(struct device_node *np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern int prom_add_property(struct device_node *np, struct property *prop);
+extern int prom_remove_property(struct device_node *np, struct property *prop);
+extern int prom_update_property(struct device_node *np,
+ struct property *newprop,
+ struct property *oldprop);
+
+#ifdef CONFIG_PPC32
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+ u8 *bus, u8 *devfn);
+extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *, int);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *);
+extern void pci_create_OF_bus_map(void);
+#endif
+
+extern struct resource *request_OF_resource(struct device_node *node,
+ int index, const char *name_postfix);
+extern int release_OF_resource(struct device_node *node, int index);
+
+/*
+ * OF address retreival & translation
+ */
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
+/* Like of_read_number, but we want an unsigned long result */
+#ifdef CONFIG_PPC32
+static inline unsigned long of_read_ulong(const u32 *cell, int size)
+{
+ return cell[size-1];
+}
+#else
+#define of_read_ulong(cell, size) of_read_number(cell, size)
+#endif
+
+/* Translate an OF address block into a CPU physical address
+ */
+extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern const u32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags);
+extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+ u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+ struct resource *r);
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+ unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/*
+ * OF interrupt mapping
+ */
+
+/* This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+
+#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
+
+struct of_irq {
+ struct device_node *controller; /* Interrupt controller node */
+ u32 size; /* Specifier size */
+ u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+/**
+ * of_irq_map_init - Initialize the irq remapper
+ * @flags: flags defining workarounds to enable
+ *
+ * Some machines have bugs in the device-tree which require certain workarounds
+ * to be applied. Call this before any interrupt mapping attempts to enable
+ * those workarounds.
+ */
+#define OF_IMAP_OLDWORLD_MAC 0x00000001
+#define OF_IMAP_NO_PHANDLE 0x00000002
+
+extern void of_irq_map_init(unsigned int flags);
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent: the device interrupt parent
+ * @intspec: interrupt specifier ("interrupts" property of the device)
+ * @ointsize: size of the passed in interrupt specifier
+ * @addr: address specifier (start of "reg" property of the device)
+ * @out_irq: structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ *
+ */
+
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+ u32 ointsize, const u32 *addr,
+ struct of_irq *out_irq);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ * It also implements the workarounds for OldWolrd Macs.
+ */
+extern int of_irq_map_one(struct device_node *device, int index,
+ struct of_irq *out_irq);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev: the device whose interrupt is to be resolved
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+extern int of_irq_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
+
+/*
+ * NB: This is here while we transition from using asm/prom.h
+ * to linux/of.h
+ */
+#include <linux/of.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_PROM_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 05/52] [microblaze] Support for semaphores
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (44 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 04/52] [microblaze] Open firmware files monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 06/52] [microblaze] exception handling monstr
` (5 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/semaphore.c | 222 ++++++++++++++++++++++++++++++++++++
include/asm-microblaze/semaphore.h | 100 ++++++++++++++++
2 files changed, 322 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/semaphore.c
create mode 100644 include/asm-microblaze/semaphore.h
diff --git a/arch/microblaze/kernel/semaphore.c b/arch/microblaze/kernel/semaphore.c
new file mode 100644
index 0000000..360fc7b
--- /dev/null
+++ b/arch/microblaze/kernel/semaphore.c
@@ -0,0 +1,222 @@
+/*
+ * arch/microblaze/kernel/semaphore.c
+ *
+ * Generic semaphore code. Buyer beware. Do your own specific changes
+ * in <asm/semaphore-helper.h>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Kevin Chea
+ */
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/init.h>
+#include <asm/semaphore.h>
+#include <asm/errno.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+
+static inline void wake_one_more(struct semaphore *sem)
+{
+ atomic_inc((atomic_t *)&sem->sleepers);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ if (sem->sleepers > 0) {
+ sem->sleepers--;
+ ret = 1;
+ }
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ * 1 got the lock
+ * 0 go to sleep
+ * -EINTR interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+ struct task_struct *tsk) {
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ if (sem->sleepers > 0) {
+ sem->sleepers--;
+ ret = 1;
+ } else if (signal_pending(tsk)) {
+ atomic_inc(&sem->count);
+ ret = -EINTR;
+ }
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ * 1 failed to lock
+ * 0 got the lock
+ *
+ * We must undo the sem->count down_trylock() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+ unsigned long flags;
+ int ret = 1;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ if (sem->sleepers <= 0)
+ atomic_inc(&sem->count);
+ else {
+ sem->sleepers--;
+ ret = 0;
+ }
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+spinlock_t semaphore_wake_lock;
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit. ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore. The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+void __up(struct semaphore *sem)
+{
+ wake_one_more(sem);
+ wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function. Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible. This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return. If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR \
+ struct task_struct *tsk = current; \
+ wait_queue_t wait; \
+ init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state) \
+ \
+ \
+ tsk->state = (task_state); \
+ add_wait_queue(&sem->wait, &wait); \
+ \
+ /* \
+ * Ok, we're set up. sem->count is known to be less than zero \
+ * so we must wait. \
+ * \
+ * We can let go the lock for purposes of waiting. \
+ * We re-acquire it after awaking so as to protect \
+ * all semaphore operations. \
+ * \
+ * If "up()" is called before we call waking_non_zero() then \
+ * we will catch it right away. If it is called later then \
+ * we will have to go through a wakeup cycle to catch it. \
+ * \
+ * Multiple waiters contend for the semaphore lock to see \
+ * who gets to gate through and who has to wait some more. \
+ */ \
+ for (;;) {
+
+#define DOWN_TAIL(task_state) \
+ tsk->state = (task_state); \
+ } \
+ tsk->state = TASK_RUNNING; \
+ remove_wait_queue(&sem->wait, &wait);
+
+void __sched __down(struct semaphore *sem) {
+ DOWN_VAR
+ DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+ if (waking_non_zero(sem))
+ break;
+ schedule();
+ DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __sched __down_interruptible(struct semaphore *sem) {
+ int ret = 0;
+ DOWN_VAR
+ DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+ ret = waking_non_zero_interruptible(sem, tsk);
+ if (ret) {
+ if (ret == 1)
+ /* ret != 0 only if we get interrupted -arca */
+ ret = 0;
+ break;
+ }
+ schedule();
+ DOWN_TAIL(TASK_INTERRUPTIBLE)
+ return ret;
+}
+
+int __down_trylock(struct semaphore *sem)
+{
+ return waking_non_zero_trylock(sem);
+}
diff --git a/include/asm-microblaze/semaphore.h b/include/asm-microblaze/semaphore.h
new file mode 100644
index 0000000..f59aae6
--- /dev/null
+++ b/include/asm-microblaze/semaphore.h
@@ -0,0 +1,100 @@
+/*
+ * include/asm-microblaze/semaphore.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_SEMAPHORE_H
+#define _ASM_SEMAPHORE_H
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+ atomic_t count;
+ int sleepers;
+ wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INITIALIZER(name,n) \
+{ \
+ .count = ATOMIC_INIT(n), \
+ .sleepers = 0, \
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+}
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
+
+static inline void sema_init(struct semaphore *sem, int val)
+{
+ atomic_set(&sem->count, val);
+ sem->sleepers = 0;
+ init_waitqueue_head(&sem->wait);
+}
+
+static inline void init_MUTEX(struct semaphore *sem)
+{
+ sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED(struct semaphore *sem)
+{
+ sema_init(sem, 0);
+}
+
+asmlinkage void __down(struct semaphore *sem);
+asmlinkage int __down_interruptible(struct semaphore *sem);
+asmlinkage int __down_trylock(struct semaphore *sem);
+asmlinkage void __up(struct semaphore *sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+static inline void down(struct semaphore *sem)
+{
+ might_sleep();
+
+ if (atomic_sub_return(1, &sem->count) < 0)
+ __down(sem);
+}
+
+static inline int down_interruptible(struct semaphore *sem)
+{
+ int ret = 0;
+
+ might_sleep();
+
+ if (atomic_sub_return(1, &sem->count) < 0)
+ ret = __down_interruptible(sem);
+ return ret;
+}
+
+static inline int down_trylock(struct semaphore *sem)
+{
+ int ret = 0;
+
+ if (atomic_sub_return(1, &sem->count) < 0)
+ ret = __down_trylock(sem);
+ return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+static inline void up(struct semaphore *sem)
+{
+ if (atomic_add_return(1, &sem->count) <= 0)
+ __up(sem);
+}
+
+#endif /* _ASM_SEMAPHORE_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 06/52] [microblaze] exception handling
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (45 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 05/52] [microblaze] Support for semaphores monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 07/52] [microblaze] Signal support monstr
` (4 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/exceptions.c | 79 +++++
arch/microblaze/kernel/hw_exception_handler.S | 395 +++++++++++++++++++++++++
include/asm-microblaze/exceptions.h | 66 ++++
3 files changed, 540 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/exceptions.c
create mode 100644 arch/microblaze/kernel/hw_exception_handler.S
create mode 100644 include/asm-microblaze/exceptions.h
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
new file mode 100644
index 0000000..9537667
--- /dev/null
+++ b/arch/microblaze/kernel/exceptions.c
@@ -0,0 +1,79 @@
+/*
+ * arch/microblaze/kernel/exceptions.c - HW exception handling
+ *
+ * Copyright 2007 Xilinx, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <asm/exceptions.h>
+#include <asm/entry.h> /* For KM CPU var */
+
+/* Initialize_exception_handlers() - called from setup.c/trap_init() */
+void initialize_exception_handlers(void)
+{
+}
+
+#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02
+#define MICROBLAZE_IOPB_BUS_EXCEPTION 0x03
+#define MICROBLAZE_DOPB_BUS_EXCEPTION 0x04
+#define MICROBLAZE_DIV_ZERO_EXCEPTION 0x05
+#define MICROBLAZE_FPU_EXCEPTION 0x06
+
+static void handle_unexpected_exception(unsigned int esr,
+ unsigned int kernel_mode, unsigned int addr)
+{
+ printk(KERN_WARNING "Unexpected exception %02x in %s mode, PC=%08x\n",
+ esr, kernel_mode ? "kernel" : "user", addr);
+}
+
+static void handle_exception(const char *message, int signal,
+ unsigned int kernel_mode, unsigned int addr)
+{
+ if (kernel_mode) {
+ panic("%s in the kernel mode, PC=%08x\n", message, addr);
+ } else {
+ force_sig(signal, current);
+ }
+}
+
+asmlinkage void other_exception_handler(unsigned int esr, unsigned int addr)
+{
+ unsigned int kernel_mode = per_cpu(KM, 0);
+
+ switch (esr) {
+
+ case MICROBLAZE_ILL_OPCODE_EXCEPTION:
+ handle_exception("Illegal instruction", SIGILL,
+ kernel_mode, addr);
+ break;
+
+ case MICROBLAZE_IOPB_BUS_EXCEPTION:
+ handle_exception("Instruction bus error", SIGBUS,
+ kernel_mode, addr);
+ break;
+
+ case MICROBLAZE_DOPB_BUS_EXCEPTION:
+ handle_exception("Data bus error", SIGBUS, kernel_mode, addr);
+ break;
+
+ case MICROBLAZE_DIV_ZERO_EXCEPTION:
+ handle_exception("Divide by zero", SIGILL, kernel_mode, addr);
+ break;
+
+ case MICROBLAZE_FPU_EXCEPTION:
+ handle_exception("FPU error", SIGFPE, kernel_mode, addr);
+ break;
+
+ default:
+ handle_unexpected_exception(esr, kernel_mode, addr);
+ }
+
+ return;
+}
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
new file mode 100644
index 0000000..4c3b41b
--- /dev/null
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -0,0 +1,395 @@
+/*
+ *
+ * arch/microblaze/kernel/hw_exception_handler.S
+ *
+ * Unaligned exception handling for Microblaze
+ *
+ * cleanup code (C) 2007 Michal Simek <monstr@monstr.eu>
+ * uClinux customisation (C) 2005 John Williams
+ *
+ * Original code
+ * Copyright (C) 2004 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Id: hw_exception_handler.S,v 1.1.2.1 2007/03/16 16:09:57 imanuilov Exp $
+ *
+ */
+
+/*
+ * Microblaze HW Exception Handler
+ * - Non self-modifying exception handler for the following exception conditions
+ * - Unalignment
+ * - Instruction bus error
+ * - Data bus error
+ * - Illegal instruction opcode
+ * - Divide-by-zero
+ *
+ * Note we disable interrupts during exception handling, otherwise we will
+ * possibly get multiple re-entrancy if interrupt handles themselves cause
+ * exceptions. JW
+ */
+
+#include <linux/autoconf.h>
+#include <asm/exceptions.h>
+#include <asm/unistd.h>
+
+/* Helpful Macros */
+#define EX_HANDLER_STACK_SIZ (4*19)
+#define RMSR_OFFSET 0
+#define REG_OFFSET(regnum) (4*regnum)
+#define NUM_TO_REG(num) r ## num
+
+#define R3_TO_STACK(regnum) swi r3, r1, REG_OFFSET(regnum)
+#define R3_FROM_STACK(regnum) lwi r3, r1, REG_OFFSET(regnum)
+
+#define PUSH_REG(regnum) swi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
+#define POP_REG(regnum) lwi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
+
+/* Uses r5 */
+#define PUSH_MSR \
+ mfs r5, rmsr; \
+ swi r5, r1, RMSR_OFFSET;
+
+#define PUSH_MSR_AND_ENABLE_EXC \
+ mfs r5, rmsr; \
+ swi r5, r1, RMSR_OFFSET; \
+ ori r5, r5, 0x100; /* Turn ON the EE bit */ \
+ andi r5, r5, ~2; /* Disable interrupts */ \
+ mts rmsr, r5;
+
+/* Uses r5 */
+#define POP_MSR \
+ lwi r5, r1, RMSR_OFFSET; \
+ mts rmsr, r5;
+
+#define LWREG_NOP \
+ bri ex_handler_unhandled; \
+ nop;
+
+#define SWREG_NOP \
+ bri ex_handler_unhandled; \
+ nop;
+
+/* r3 is the source */
+#define R3_TO_LWREG_V(regnum) \
+ R3_TO_STACK(regnum); \
+ bri ex_handler_done;
+
+/* r3 is the source */
+#define R3_TO_LWREG(regnum) \
+ or NUM_TO_REG (regnum), r0, r3; \
+ bri ex_handler_done;
+
+/* r3 is the target */
+#define SWREG_TO_R3_V(regnum) \
+ R3_FROM_STACK (regnum); \
+ bri ex_sw_tail;
+
+/* r3 is the target */
+#define SWREG_TO_R3(regnum) \
+ or r3, r0, NUM_TO_REG (regnum); \
+ bri ex_sw_tail;
+
+.extern other_exception_handler /* Defined in exception.c */
+
+/*
+ * hw_exception_handler - Handler for unaligned exceptions
+ * Exception handler notes:
+ * - Does not handle exceptions other than unaligned exceptions
+ * - Does not handle exceptions during load into r17, r1, r0.
+ * - Does not handle exceptions during store from r17 (cannot be done)
+ * and r1 (slows down common case)
+ *
+ * Relevant register structures
+ *
+ * EAR - |----|----|----|----|----|----|----|----|
+ * - < ## 32 bit faulting address ## >
+ *
+ * ESR - |----|----|----|----|----| - | - |-----|-----|
+ * - W S REG EXC
+ *
+ *
+ * STACK FRAME STRUCTURE
+ * ---------------------
+ *
+ * +-------------+ + 0
+ * | MSR |
+ * +-------------+ + 4
+ * | r1 |
+ * | . |
+ * | . |
+ * | . |
+ * | . |
+ * | r18 |
+ * +-------------+ + 76
+ * | . |
+ * | . |
+ */
+
+.global _hw_exception_handler
+.section .text
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:
+ addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
+ PUSH_REG(3);
+ PUSH_REG(4);
+ PUSH_REG(5);
+ PUSH_REG(6);
+ mfs r3, resr;
+
+ andi r5, r3, 0x1000;
+ beqi r5, not_in_delay_slot;
+ mfs r17, rbtr;
+not_in_delay_slot:
+
+ PUSH_REG(17);
+ /* Exceptions enabled here. This will allow nested exceptions */
+ PUSH_MSR_AND_ENABLE_EXC;
+
+ andi r5, r3, 0x1F; /* Extract ESR[EXC] */
+
+ xori r6, r5, 1; /* 00001 = Unaligned Exception */
+ /* Jump to unalignment exception handler */
+ beqi r6, handle_unaligned_ex;
+
+handle_other_ex: /* Handle Other exceptions here */
+ /* Save other volatiles before we make procedure calls below */
+ PUSH_REG(7);
+ PUSH_REG(8);
+ PUSH_REG(9);
+ PUSH_REG(10);
+ PUSH_REG(11);
+ PUSH_REG(12);
+ PUSH_REG(14);
+ PUSH_REG(15);
+ PUSH_REG(18);
+
+ andi r5, r3, 0x1F; /* Load ESR[EC] */
+ addk r6, r17, r0; /* Load exception address */
+ bralid r15, other_exception_handler; /* Branch to the handler */
+ nop;
+
+ /*
+ * Trigger execution of the signal handler by enabling
+ * interrupts and calling an invalid syscall.
+ */
+ mfs r5, rmsr;
+ ori r5, r5, 2;
+ mts rmsr, r5;
+ addi r12, r0, NR_syscalls;
+ brki r14, 0x08;
+ mfs r5, rmsr;
+ andi r5, r5, ~2;
+ mts rmsr, r5;
+
+ POP_REG(7); /* Restore other volatiles */
+ POP_REG(8);
+ POP_REG(9);
+ POP_REG(10);
+ POP_REG(11);
+ POP_REG(12);
+ POP_REG(14);
+ POP_REG(15);
+ POP_REG(18);
+
+ bri ex_handler_done; /* Complete exception handling */
+handle_unaligned_ex:
+ andi r6, r3, 0x3E0; /* Mask and extract the register operand */
+ srl r6, r6; /* r6 >> 5 */
+ srl r6, r6;
+ srl r6, r6;
+ srl r6, r6;
+ srl r6, r6;
+ /* Store the register operand in a temporary location */
+ sbi r6, r0, ex_reg_op;
+ mfs r4, rear;
+ andi r6, r3, 0x400; /* Extract ESR[S] */
+ bnei r6, ex_sw;
+ex_lw:
+ andi r6, r3, 0x800; /* Extract ESR[W] */
+ beqi r6, ex_lhw;
+ lbui r5, r4, 0; /* Exception address in r4 */
+ /* Load a word, byte-by-byte from destination address
+ and save it in tmp space */
+ sbi r5, r0, ex_tmp_data_loc_0;
+ lbui r5, r4, 1;
+ sbi r5, r0, ex_tmp_data_loc_1;
+ lbui r5, r4, 2;
+ sbi r5, r0, ex_tmp_data_loc_2;
+ lbui r5, r4, 3;
+ sbi r5, r0, ex_tmp_data_loc_3;
+ /* Get the destination register value into r3 */
+ lwi r3, r0, ex_tmp_data_loc_0;
+ bri ex_lw_tail;
+ex_lhw:
+ lbui r5, r4, 0; /* Exception address in r4 */
+ /* Load a half-word, byte-by-byte from destination
+ address and save it in tmp space */
+ sbi r5, r0, ex_tmp_data_loc_0;
+ lbui r5, r4, 1;
+ sbi r5, r0, ex_tmp_data_loc_1;
+ /* Get the destination register value into r3 */
+ lhui r3, r0, ex_tmp_data_loc_0;
+ex_lw_tail:
+ /* Get the destination register number into r5 */
+ lbui r5, r0, ex_reg_op;
+ /* Form load_word jump table offset (lw_table + (8 * regnum)) */
+ la r6, r0, lw_table;
+ addk r5, r5, r5;
+ addk r5, r5, r5;
+ addk r5, r5, r5;
+ addk r5, r5, r6;
+ bra r5;
+ex_lw_end: /* Exception handling of load word, ends */
+ex_sw:
+ /* Get the destination register number into r5 */
+ lbui r5, r0, ex_reg_op;
+ /* Form store_word jump table offset (sw_table + (8 * regnum)) */
+ la r6, r0, sw_table;
+ add r5, r5, r5;
+ add r5, r5, r5;
+ add r5, r5, r5;
+ add r5, r5, r6;
+ bra r5;
+ex_sw_tail:
+ mfs r6, resr;
+ andi r6, r6, 0x800; /* Extract ESR[W] */
+ beqi r6, ex_shw;
+ swi r3, r0, ex_tmp_data_loc_0;
+ /* Store the word, byte-by-byte into destination address */
+ lbui r3, r0, ex_tmp_data_loc_0;
+ sbi r3, r4, 0;
+ lbui r3, r0, ex_tmp_data_loc_1;
+ sbi r3, r4, 1;
+ lbui r3, r0, ex_tmp_data_loc_2;
+ sbi r3, r4, 2;
+ lbui r3, r0, ex_tmp_data_loc_3;
+ sbi r3, r4, 3;
+ bri ex_handler_done;
+ex_shw:
+ /* Store the lower half-word, byte-by-byte into destination address */
+ swi r3, r0, ex_tmp_data_loc_0;
+ lbui r3, r0, ex_tmp_data_loc_2;
+ sbi r3, r4, 0;
+ lbui r3, r0, ex_tmp_data_loc_3;
+ sbi r3, r4, 1;
+ex_sw_end: /* Exception handling of store word, ends. */
+
+ex_handler_done:
+ POP_MSR;
+ POP_REG(3);
+ POP_REG(4);
+ POP_REG(5);
+ POP_REG(6);
+ POP_REG(17);
+ rted r17, 0
+ addik r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */
+ex_handler_unhandled:
+ bri 0 /* UNHANDLED. TRAP HERE */
+.end _hw_exception_handler
+
+/*
+* hw_exception_handler Jump Table
+* - Contains code snippets for each register that caused the unaligned exception
+* - Hence exception handler is NOT self-modifying
+* - Separate table for load exceptions and store exceptions.
+* - Each table is of size: (8 * 32) = 256 bytes
+*/
+
+.section .text
+.align 4
+lw_table:
+lw_r0: R3_TO_LWREG (0);
+lw_r1: LWREG_NOP;
+lw_r2: R3_TO_LWREG (2);
+lw_r3: R3_TO_LWREG_V (3);
+lw_r4: R3_TO_LWREG_V (4);
+lw_r5: R3_TO_LWREG_V (5);
+lw_r6: R3_TO_LWREG_V (6);
+lw_r7: R3_TO_LWREG (7);
+lw_r8: R3_TO_LWREG (8);
+lw_r9: R3_TO_LWREG (9);
+lw_r10: R3_TO_LWREG (10);
+lw_r11: R3_TO_LWREG (11);
+lw_r12: R3_TO_LWREG (12);
+lw_r13: R3_TO_LWREG (13);
+lw_r14: R3_TO_LWREG (14);
+lw_r15: R3_TO_LWREG (15);
+lw_r16: R3_TO_LWREG (16);
+lw_r17: LWREG_NOP;
+lw_r18: R3_TO_LWREG (18);
+lw_r19: R3_TO_LWREG (19);
+lw_r20: R3_TO_LWREG (20);
+lw_r21: R3_TO_LWREG (21);
+lw_r22: R3_TO_LWREG (22);
+lw_r23: R3_TO_LWREG (23);
+lw_r24: R3_TO_LWREG (24);
+lw_r25: R3_TO_LWREG (25);
+lw_r26: R3_TO_LWREG (26);
+lw_r27: R3_TO_LWREG (27);
+lw_r28: R3_TO_LWREG (28);
+lw_r29: R3_TO_LWREG (29);
+lw_r30: R3_TO_LWREG (30);
+lw_r31: R3_TO_LWREG (31);
+
+sw_table:
+sw_r0: SWREG_TO_R3 (0);
+sw_r1: SWREG_NOP;
+sw_r2: SWREG_TO_R3 (2);
+sw_r3: SWREG_TO_R3_V (3);
+sw_r4: SWREG_TO_R3_V (4);
+sw_r5: SWREG_TO_R3_V (5);
+sw_r6: SWREG_TO_R3_V (6);
+sw_r7: SWREG_TO_R3 (7);
+sw_r8: SWREG_TO_R3 (8);
+sw_r9: SWREG_TO_R3 (9);
+sw_r10: SWREG_TO_R3 (10);
+sw_r11: SWREG_TO_R3 (11);
+sw_r12: SWREG_TO_R3 (12);
+sw_r13: SWREG_TO_R3 (13);
+sw_r14: SWREG_TO_R3 (14);
+sw_r15: SWREG_TO_R3 (15);
+sw_r16: SWREG_TO_R3 (16);
+sw_r17: SWREG_NOP;
+sw_r18: SWREG_TO_R3 (18);
+sw_r19: SWREG_TO_R3 (19);
+sw_r20: SWREG_TO_R3 (20);
+sw_r21: SWREG_TO_R3 (21);
+sw_r22: SWREG_TO_R3 (22);
+sw_r23: SWREG_TO_R3 (23);
+sw_r24: SWREG_TO_R3 (24);
+sw_r25: SWREG_TO_R3 (25);
+sw_r26: SWREG_TO_R3 (26);
+sw_r27: SWREG_TO_R3 (27);
+sw_r28: SWREG_TO_R3 (28);
+sw_r29: SWREG_TO_R3 (29);
+sw_r30: SWREG_TO_R3 (30);
+sw_r31: SWREG_TO_R3 (31);
+
+/* Temporary data structures used in the handler */
+.section .data
+.align 4
+ex_tmp_data_loc_0:
+ .byte 0
+ex_tmp_data_loc_1:
+ .byte 0
+ex_tmp_data_loc_2:
+ .byte 0
+ex_tmp_data_loc_3:
+ .byte 0
+ex_reg_op:
+ .byte 0
+
diff --git a/include/asm-microblaze/exceptions.h b/include/asm-microblaze/exceptions.h
new file mode 100644
index 0000000..3230cc0
--- /dev/null
+++ b/include/asm-microblaze/exceptions.h
@@ -0,0 +1,66 @@
+/*
+ * include/asm-microblaze/exceptions.h
+ *
+ * Preliminary support for HW exception handing for Microblaze
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _ASM_EXCEPTIONS_H
+#define _ASM_EXCEPTIONS_H
+
+#include <linux/autoconf.h>
+
+#ifndef __ASSEMBLY__
+
+void initialize_exception_handlers(void);
+asmlinkage void other_exception_handler(unsigned int esr, unsigned int addr);
+
+/* Macros to enable and disable HW exceptions in the MSR */
+/* Define MSR enable bit for HW exceptions */
+#define HWEX_MSR_BIT (1 << 8)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_hw_exceptions() \
+ __asm__ __volatile__ (" msrset r0, %0; \
+ nop; " \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory")
+
+#define __disable_hw_exceptions() \
+ __asm__ __volatile__ (" msrclr r0, %0; \
+ nop; " \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory")
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_hw_exceptions() \
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory", "r12")
+
+#define __disable_hw_exceptions() \
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory", "r12")
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#endif /*__ASSEMBLY__ */
+
+#endif /* _ASM_EXCEPTIONS_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 07/52] [microblaze] Signal support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (46 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 06/52] [microblaze] exception handling monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 08/52] [microblaze] Interrupt handling, timer support, supported function monstr
` (3 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/signal.c | 534 +++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/signal.h | 199 +++++++++++++++
2 files changed, 733 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/signal.c
create mode 100644 include/asm-microblaze/signal.h
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
new file mode 100644
index 0000000..5b45387
--- /dev/null
+++ b/arch/microblaze/kernel/signal.c
@@ -0,0 +1,534 @@
+/*
+ * arch/microblaze/kernel/signal.c -- Signal handling
+ *
+ * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001 NEC Corporation
+ * Copyright (C) 2001 Miles Bader <miles@gnu.org>
+ * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 1991,1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was was derived from the sh version, arch/sh/kernel/signal.c
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/percpu.h>
+#include <asm/entry.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/signal.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+ sigset_t saveset;
+
+ mask &= _BLOCKABLE;
+ spin_lock_irq(¤t->sighand->siglock);
+ saveset = current->blocked;
+ siginitset(¤t->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ regs->r3 = -EINTR;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(regs, &saveset, 1))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+ struct pt_regs *regs)
+{
+ sigset_t saveset, newset;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (copy_from_user(&newset, unewset, sizeof(newset)))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+ spin_lock_irq(¤t->sighand->siglock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ regs->r3 = -EINTR;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(regs, &saveset, 1))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+ struct old_sigaction *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs)
+{
+ return do_sigaltstack(uss, uoss, regs->r1);
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe {
+ struct sigcontext sc;
+ unsigned long extramask[_NSIG_WORDS-1];
+ unsigned long tramp[2]; /* signal trampoline */
+};
+
+struct rt_sigframe {
+ struct siginfo info;
+ struct ucontext uc;
+ unsigned long tramp[2]; /* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+ unsigned int err = 0;
+
+#define COPY(x) err |= __get_user(regs->x, &sc->regs.x)
+ COPY(r0); COPY(r1);
+ COPY(r2); COPY(r3); COPY(r4); COPY(r5);
+ COPY(r6); COPY(r7); COPY(r8); COPY(r9);
+ COPY(r10); COPY(r11); COPY(r12); COPY(r13);
+ COPY(r14); COPY(r15); COPY(r16); COPY(r17);
+ COPY(r18); COPY(r19); COPY(r20); COPY(r21);
+ COPY(r22); COPY(r23); COPY(r24); COPY(r25);
+ COPY(r26); COPY(r27); COPY(r28); COPY(r29);
+ COPY(r30); COPY(r31);
+ COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
+#undef COPY
+
+ * rval_p = regs->r3;
+
+ return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+ struct sigframe *frame = (struct sigframe *)regs->r1;
+ sigset_t set;
+ int rval;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+
+ if (__get_user(set.sig[0], &frame->sc.oldmask)
+ || (_NSIG_WORDS > 1
+ && __copy_from_user(&set.sig[1], &frame->extramask,
+ sizeof(frame->extramask))))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+
+ spin_lock_irq(¤t->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->sc, &rval))
+ goto badframe;
+ return rval;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe *frame = (struct rt_sigframe *)regs->r1;
+ sigset_t set;
+ stack_t st;
+ int rval;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(¤t->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+ goto badframe;
+
+ if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st)))
+ goto badframe;
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ do_sigaltstack(&st, NULL, regs->r1);
+
+ return rval;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ int err = 0;
+
+#define COPY(x) err |= __put_user(regs->x, &sc->regs.x)
+ COPY(r0); COPY(r1);
+ COPY(r2); COPY(r3); COPY(r4); COPY(r5);
+ COPY(r6); COPY(r7); COPY(r8); COPY(r9);
+ COPY(r10); COPY(r11); COPY(r12); COPY(r13);
+ COPY(r14); COPY(r15); COPY(r16); COPY(r17);
+ COPY(r18); COPY(r19); COPY(r20); COPY(r21);
+ COPY(r22); COPY(r23); COPY(r24); COPY(r25);
+ COPY(r26); COPY(r27); COPY(r28); COPY(r29);
+ COPY(r30); COPY(r31);
+ COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
+#undef COPY
+
+ err |= __put_user(mask, &sc->oldmask);
+
+ return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ /* Default to using normal stack */
+ unsigned long sp = regs->r1;
+
+ if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct sigframe *frame;
+ int err = 0;
+ int signal;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ signal = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+ if (_NSIG_WORDS > 1) {
+ err |= __copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+ }
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ /* minus 8 is offset to cater for "rtsd r15,8" offset */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+ } else {
+ /* Note, these encodings are _big endian_! */
+
+ /* addi r12, r0, __NR_sigreturn */
+ err |= __put_user(0x31800000 | __NR_sigreturn ,
+ frame->tramp + 0);
+ /* brki r14, 0x8 */
+ err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+ /* Return from sighandler will jump to the tramp.
+ Negative 8 offset because return is rtsd r15, 8 */
+ regs->r15 = ((unsigned long)frame->tramp)-8;
+
+#if 0
+ flush_cache_sigtramp((unsigned long)frame->tramp);
+#endif
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ regs->r1 = (unsigned long) frame;
+ /* Signal handler args: */
+ regs->r5 = signal; /* Arg 0: signum */
+ regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */
+
+ /* Offset of 4 to handle microblaze rtid r14, 0 */
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+
+ set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+ current->comm, current->pid, frame, regs->pc);
+#endif
+
+ return;
+
+give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+ int signal;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ signal = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __put_user((void *)current->sas_ss_sp,
+ &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->r1),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext,
+ regs, set->sig[0]);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ /* minus 8 is offset to cater for "rtsd r15,8" */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+ } else {
+ /* addi r12, r0, __NR_sigreturn */
+ err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
+ frame->tramp + 0);
+ /* brki r14, 0x8 */
+ err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+ /* Return from sighandler will jump to the tramp.
+ Negative 8 offset because return is rtsd r15, 8 */
+ regs->r15 = ((unsigned long)frame->tramp)-8;
+
+#if 0
+ flush_cache_sigtramp((unsigned long)frame->tramp);
+#endif
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ regs->r1 = (unsigned long) frame;
+ /* Signal handler args: */
+ regs->r5 = signal; /* arg 0: signum */
+ regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
+ regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
+ /* Offset to handle microblaze rtid r14, 0 */
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+
+ set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+ current->comm, current->pid, frame, regs->pc);
+#endif
+
+ return;
+
+give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+}
+
+/* Handle restarting system calls */
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->r3) {
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->r3 = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->r3 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+do_restart:
+ /* offset of 4 bytes to re-execute trap (brki) instruction */
+ regs->pc -= 4;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+{
+ /* Set up the stack frame */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(sig, ka, info, oldset, regs);
+ else
+ setup_frame(sig, ka, oldset, regs);
+
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
+
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
+ spin_lock_irq(¤t->sighand->siglock);
+ sigorsets(¤t->blocked,
+ ¤t->blocked, &ka->sa.sa_mask);
+ sigaddset(¤t->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+ }
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+{
+ siginfo_t info;
+ int signr;
+ struct k_sigaction ka;
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall);
+ printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
+ regs->r12, current_thread_info()->flags);
+#endif
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if (!user_mode(regs))
+ return 1;
+
+ if (!oldset)
+ oldset = ¤t->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (in_syscall)
+ handle_restart(regs, &ka, 1);
+ handle_signal(signr, &ka, &info, oldset, regs);
+ return 1;
+ }
+
+ if (in_syscall)
+ handle_restart(regs, NULL, 0);
+
+ /* Did we come from a system call? */
+ return 0;
+}
diff --git a/include/asm-microblaze/signal.h b/include/asm-microblaze/signal.h
new file mode 100644
index 0000000..85e55f6
--- /dev/null
+++ b/include/asm-microblaze/signal.h
@@ -0,0 +1,199 @@
+/*
+ * include/asm-microblaze/signal.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * Authors:
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
+ */
+
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <linux/linkage.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifdef __KERNEL__
+
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+#define _NSIG 64
+#define _NSIG_BPW 32
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+#else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+
+typedef struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+
+asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs);
+asmlinkage int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+ struct pt_regs *regs);
+asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act,
+ struct old_sigaction *oact);
+asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs);
+asmlinkage int sys_sigreturn(struct pt_regs *regs);
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
+
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_SIGNAL_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 08/52] [microblaze] Interrupt handling, timer support, supported function
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (47 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 07/52] [microblaze] Signal support monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:03 ` [PATCH 09/52] [microblaze] cache support monstr
` (2 subsequent siblings)
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/hack.c | 88 +++++++++++++++++++++++++
arch/microblaze/kernel/intc.c | 141 ++++++++++++++++++++++++++++++++++++++++
arch/microblaze/kernel/irq.c | 88 +++++++++++++++++++++++++
arch/microblaze/kernel/timer.c | 134 ++++++++++++++++++++++++++++++++++++++
include/asm-microblaze/hack.h | 19 ++++++
include/asm-microblaze/irq.h | 34 ++++++++++
6 files changed, 504 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/hack.c
create mode 100644 arch/microblaze/kernel/intc.c
create mode 100644 arch/microblaze/kernel/irq.c
create mode 100644 arch/microblaze/kernel/timer.c
create mode 100644 include/asm-microblaze/hack.h
create mode 100644 include/asm-microblaze/irq.h
diff --git a/arch/microblaze/kernel/hack.c b/arch/microblaze/kernel/hack.c
new file mode 100644
index 0000000..627f06d
--- /dev/null
+++ b/arch/microblaze/kernel/hack.c
@@ -0,0 +1,88 @@
+/*
+ * arch/microblaze/kernel/hack.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ */
+
+#include <linux/interrupt.h>
+#include <asm/hack.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/* NOTE
+ * self-modified part of code for improvement of interrupt controller
+ * save instruction in interrupt rutine
+ */
+void function_hack(const int *arr_fce, const unsigned int base)
+{
+ unsigned int flags = 0;
+ unsigned int j, i;
+ unsigned int *addr = NULL;
+
+ local_irq_save(flags);
+ __disable_icache();
+
+ /* zero terminated array */
+ for (j = 0; arr_fce[j] != 0; j++) {
+ /* get start address of function */
+ addr = (unsigned int *) arr_fce[j];
+ DBG("%s: func(%d) at 0x%x\n",
+ __FUNCTION__, j, (unsigned int) addr);
+ for (i = 0;; i++) {
+ DBG("%s: instruction code at %d: 0x%x\n",
+ __FUNCTION__, i, addr[i]);
+ if (addr[i] == 0xb0001234) {
+ /* detecting of lwi or swi instruction */
+ if ((addr[i+1] & 0xec00ff00) == 0xe800ff00) {
+ DBG("%s: curr instr, "
+ "(%d):0x%x, "
+ "next(%d):0x%x\n",
+ __FUNCTION__, i, addr[i], i+1,
+ addr[i+1]);
+ addr[i] = 0xb0000000 + (base >> 16);
+ addr[i+1] = (addr[i+1] & 0xffff00ff) +
+ (base & 0xffff);
+ __invalidate_icache(addr[i]);
+ __invalidate_icache(addr[i+1]);
+ DBG("%s: hack instr, "
+ "(%d):0x%x, "
+ "next(%d):0x%x\n",
+ __FUNCTION__, i, addr[i], i+1,
+ addr[i+1]);
+ } else /* detection addik for ack */
+ if ((addr[i+1] & 0xfc00ff00) == 0x3000ff00) {
+ DBG("%s: curr instr, "
+ "(%d):0x%x, "
+ "next(%d):0x%x\n",
+ __FUNCTION__, i, addr[i], i+1,
+ addr[i+1]);
+ addr[i] = 0xb0000000 + (base >> 16);
+ addr[i+1] = (addr[i+1] & 0xffff00ff) +
+ (base & 0xffff);
+ __invalidate_icache(addr[i]);
+ __invalidate_icache(addr[i+1]);
+ DBG("%s: hack instr, "
+ "(%d):0x%x, "
+ "next(%d):0x%x\n",
+ __FUNCTION__, i, addr[i], i+1,
+ addr[i+1]);
+ }
+ } else if (addr[i] == 0xb60f0008) {
+ DBG("%s: end of array %d\n",
+ __FUNCTION__, i);
+ break;
+ }
+ }
+ }
+ local_irq_restore(flags);
+} /* end of self-modified code */
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
new file mode 100644
index 0000000..7ed6a3a
--- /dev/null
+++ b/arch/microblaze/kernel/intc.c
@@ -0,0 +1,141 @@
+/*
+ * arch/microblaze/kernel/intc.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/autoconf.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/prom.h>
+#include <asm/irq.h>
+#include <asm/hack.h>
+unsigned int NR_IRQ;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00 /* Interrupt Status Register */
+#define IPR 0x04 /* Interrupt Pending Register */
+#define IER 0x08 /* Interrupt Enable Register */
+#define IAR 0x0c /* Interrupt Acknowledge Register */
+#define SIE 0x10 /* Set Interrupt Enable bits */
+#define CIE 0x14 /* Clear Interrupt Enable bits */
+#define IVR 0x18 /* Interrupt Vector Register */
+#define MER 0x1c /* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static void __init opb_intc_enable(unsigned int irq)
+{
+ unsigned int mask = (0x00000001 << (irq & 31));
+ pr_debug("enable: %d\n", irq);
+ iowrite32(mask, HACK_BASE_ADDR + SIE);
+}
+
+static void opb_intc_disable(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+ pr_debug("disable: %d\n", irq);
+ iowrite32(mask, HACK_BASE_ADDR + CIE);
+}
+
+static void opb_intc_disable_and_ack(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+ pr_debug("disable_and_ack: %d\n", irq);
+ iowrite32(mask, HACK_BASE_ADDR + CIE);
+ /* ack edge triggered intr */
+ if (!(irq_desc[irq].status & IRQ_LEVEL))
+ iowrite32(mask, HACK_BASE_ADDR + IAR);
+}
+
+static void opb_intc_end(unsigned int irq)
+{
+ unsigned long mask = (0x00000001 << (irq & 31));
+
+ pr_debug("end: %d\n", irq);
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ iowrite32(mask, HACK_BASE_ADDR + SIE);
+ /* ack level sensitive intr */
+ if (irq_desc[irq].status & IRQ_LEVEL)
+ iowrite32(mask, HACK_BASE_ADDR + IAR);
+ }
+}
+
+static struct irq_chip opb_intc = {
+ .name = "OPB-INTC",
+ .enable = opb_intc_enable,
+ .disable = opb_intc_disable,
+ .ack = opb_intc_disable_and_ack,
+ .end = opb_intc_end,
+};
+
+unsigned int get_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ /*
+ * NOTE: This function is the one that needs to be improved in
+ * order to handle multiple interrupt controllers. It currently
+ * is hardcoded to check for interrupts only on the first INTC.
+ */
+
+ irq = ioread32(HACK_BASE_ADDR + IVR);
+ pr_debug("get_irq: %d\n", irq);
+
+ return irq;
+}
+
+void __init init_IRQ(void)
+{
+ int i = 0;
+ unsigned int intc_baseaddr = 0;
+ int handle = 0x010;
+ struct device_node *intc;
+ int arr_func[] = {
+ (int)&get_irq,
+ (int)&opb_intc_enable,
+ (int)&opb_intc_disable,
+ (int)&opb_intc_disable_and_ack,
+ (int)&opb_intc_end,
+ 0
+ };
+
+ intc = of_find_compatible_node(NULL, NULL, "xlnx,opb-intc");
+ intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+ /* intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); */
+ NR_IRQ = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+
+ function_hack((int *) arr_func, intc_baseaddr);
+
+ printk(KERN_INFO "OPB INTC #0 at 0x%08lX, handle 0x%x\n",
+ (unsigned long) intc_baseaddr, handle);
+
+ /*
+ * Disable all external interrupts until they are
+ * explicity requested.
+ */
+ iowrite32(0, intc_baseaddr + IER);
+
+ /* Acknowledge any pending interrupts just in case. */
+ iowrite32(0xffffffff, intc_baseaddr + IAR);
+
+ /* Turn on the Master Enable. */
+ iowrite32(MER_HIE|MER_ME, intc_baseaddr + MER);
+
+ for (i = 0; i < NR_IRQ; ++i) {
+ irq_desc[i].chip = &opb_intc;
+
+ if (handle & (0x00000001 << i))
+ irq_desc[i].status &= ~IRQ_LEVEL;
+ else
+ irq_desc[i].status |= IRQ_LEVEL;
+ }
+}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
new file mode 100644
index 0000000..9b27199
--- /dev/null
+++ b/arch/microblaze/kernel/irq.c
@@ -0,0 +1,88 @@
+/*
+ * arch/microblaze/kernel/process.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/irqflags.h>
+#include <linux/seq_file.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+void do_IRQ(struct pt_regs *regs)
+{
+ unsigned int irq;
+
+ irq_enter();
+ set_irq_regs(regs);
+ irq = get_irq(regs);
+ BUG_ON(irq == -1U);
+ __do_IRQ(irq);
+
+ irq_exit();
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v, j;
+ struct irqaction *action;
+ unsigned long flags;
+
+ if (i == 0) {
+ seq_printf(p, " ");
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%-8d", j);
+ seq_putc(p, '\n');
+ }
+
+ if (i < NR_IRQ) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto skip;
+ seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+ seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+ seq_printf(p, " %8s", irq_desc[i].status &
+ IRQ_LEVEL ? "level": "edge");
+ seq_printf(p, " %8s", irq_desc[i].chip->name);
+ seq_printf(p, " %s", action->name);
+
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+ seq_putc(p, '\n');
+skip:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+ return 0;
+}
+
+/*unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+ printk ("ERROR %s\n",__FUNCTION__);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);*/
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
new file mode 100644
index 0000000..a686cd7
--- /dev/null
+++ b/arch/microblaze/kernel/timer.c
@@ -0,0 +1,134 @@
+/*
+ * arch/microblaze/kernel/timer.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <asm/cpuinfo.h>
+#include <asm/setup.h>
+
+#include <asm/prom.h>
+#include <asm/hack.h>
+#include <asm/irq.h>
+
+#define TCSR0 (0x00)
+#define TLR0 (0x04)
+#define TCR0 (0x08)
+#define TCSR1 (0x10)
+#define TLR1 (0x14)
+#define TCR1 (0x18)
+
+#define TCSR_MDT (1<<0)
+#define TCSR_UDT (1<<1)
+#define TCSR_GENT (1<<2)
+#define TCSR_CAPT (1<<3)
+#define TCSR_ARHT (1<<4)
+#define TCSR_LOAD (1<<5)
+#define TCSR_ENIT (1<<6)
+#define TCSR_ENT (1<<7)
+#define TCSR_TINT (1<<8)
+#define TCSR_PWMA (1<<9)
+#define TCSR_ENALL (1<<10)
+
+static void timer_ack(void)
+{
+ iowrite32(ioread32(HACK_BASE_ADDR + TCSR0), HACK_BASE_ADDR + TCSR0);
+}
+
+irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ heartbeat();
+
+ timer_ack();
+
+ write_seqlock(&xtime_lock);
+
+ do_timer(1);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
+
+ write_sequnlock(&xtime_lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction timer_irqaction = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "timer",
+};
+
+unsigned long do_gettimeoffset(void)
+{
+ /* Current counter value */
+ unsigned int tcr = ioread32(HACK_BASE_ADDR + TCR0);
+
+ /* Load register value (couting down */
+ unsigned int tcmp = ioread32(HACK_BASE_ADDR + TLR0);
+
+ /* Offset, in nanoseconds */
+ /* FIXME remove loading from structure - build in is faster */
+ unsigned long offset = (tcmp-tcr)/(cpuinfo->cpu_clock_freq/1000000);
+
+ return offset;
+}
+
+void system_timer_init(void)
+{
+ int irq = 0;
+ struct device_node *timer;
+ unsigned int timer_baseaddr = 0;
+ int arr_func[] = {
+ (int)&do_gettimeoffset,
+ (int)&timer_ack,
+ 0
+ };
+
+ timer = of_find_compatible_node(NULL, NULL, "xlnx,opb-timer");
+ timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+ /* timer_baseaddr =
+ (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); */
+ irq = *(int *) of_get_property(timer, "interrupts", NULL);
+
+ function_hack((int *) arr_func, timer_baseaddr);
+
+ printk(KERN_INFO "OPB TIMER #0 at 0x%08x, irq=%d\n",
+ timer_baseaddr, irq);
+
+ /* set the initial value to the load register */
+ iowrite32(cpuinfo->cpu_clock_freq/HZ, timer_baseaddr + TLR0);
+
+ /* load the initial value */
+ iowrite32(TCSR_LOAD, timer_baseaddr + TCSR0);
+
+ /* see opb timer data sheet for detail
+ * !ENALL - don't enable 'em all
+ * !PWMA - disable pwm
+ * TINT - clear interrupt status
+ * ENT- enable timer itself
+ * EINT - enable interrupt
+ * !LOAD - clear the bit to let go
+ * ARHT - auto reload
+ * !CAPT - no external trigger
+ * !GENT - no external signal
+ * UDT - set the timer as down counter
+ * !MDT0 - generate mode
+ *
+ */
+ iowrite32(TCSR_TINT|TCSR_ENT|TCSR_ENIT|TCSR_ARHT|TCSR_UDT,
+ timer_baseaddr + TCSR0);
+
+ setup_irq(irq, &timer_irqaction);
+}
diff --git a/include/asm-microblaze/hack.h b/include/asm-microblaze/hack.h
new file mode 100644
index 0000000..5bfd557
--- /dev/null
+++ b/include/asm-microblaze/hack.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-microblaze/hack.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ */
+
+/*
+ * HACK_BASE_ADDR is constant address for hack function.
+ * do not change this value - it is hardcoded in hack function
+ * arch/microblaze/kernel/hack.c:function_hack()
+ */
+
+#define HACK_BASE_ADDR 0x1234ff00
+
+void function_hack(const int *arr_fce, const unsigned int base);
diff --git a/include/asm-microblaze/irq.h b/include/asm-microblaze/irq.h
new file mode 100644
index 0000000..1d9b9c4
--- /dev/null
+++ b/include/asm-microblaze/irq.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-microblaze/irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+#include <linux/seq_file.h>
+#define NR_IRQS 32
+#include <linux/irq.h>
+
+extern unsigned int NR_IRQ;
+extern void ledoff(void);
+
+#define NO_IRQ (-1)
+
+static inline int irq_canonicalize(int irq)
+{
+ return (irq);
+}
+
+struct pt_regs;
+extern void do_IRQ(struct pt_regs *regs);
+extern void __init init_IRQ(void);
+int show_interrupts(struct seq_file *p, void *v);
+irqreturn_t timer_interrupt(int irq, void *dev_id);
+
+#endif /* _ASM_IRQ_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 09/52] [microblaze] cache support
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (48 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 08/52] [microblaze] Interrupt handling, timer support, supported function monstr
@ 2008-01-24 15:03 ` monstr
2008-01-24 15:05 ` [PATCH 02/52] [microblaze] Makefiles for Microblaze cpu monstr
2008-01-26 17:36 ` [PATCH 01/52] [microblaze] Kconfig patches Randy Dunlap
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:03 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams, microblaze-uclinux
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/kernel/cpu/cache.c | 256 +++++++++++++++++++++++++++++++++++
include/asm-microblaze/cache.h | 47 +++++++
include/asm-microblaze/cacheflush.h | 72 ++++++++++
3 files changed, 375 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/kernel/cpu/cache.c
create mode 100644 include/asm-microblaze/cache.h
create mode 100644 include/asm-microblaze/cacheflush.h
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
new file mode 100644
index 0000000..43fff59
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -0,0 +1,256 @@
+/*
+ * arch/microblaze/kernel/cpu/cache.c
+ * Cache control for MicroBlaze cache memories
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#include <asm/cacheflush.h>
+#include <asm/cache.h>
+#include <asm/cpuinfo.h>
+
+/* Exported functions */
+
+void _enable_icache(void)
+{
+ if (cpuinfo->use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrset r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _disable_icache(void)
+{
+ if (cpuinfo->use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrclr r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _invalidate_icache(unsigned int addr)
+{
+ if (cpuinfo->use_icache) {
+ __asm__ __volatile__ (" \
+ wic %0, r0" \
+ : \
+ : "r" (addr));
+ }
+}
+
+void _enable_dcache(void)
+{
+ if (cpuinfo->use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrset r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _disable_dcache(void)
+{
+ if (cpuinfo->use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrclr r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _invalidate_dcache(unsigned int addr)
+{
+ if (cpuinfo->use_dcache)
+ __asm__ __volatile__ (" \
+ wdc %0, r0" \
+ : \
+ : "r" (addr));
+}
+
+void __flush_icache_all(void)
+{
+ unsigned int i;
+ unsigned flags;
+
+ if (cpuinfo->use_icache) {
+ local_irq_save(flags);
+ __disable_icache();
+
+ /* Just loop through cache size and invalidate, no need to add
+ CACHE_BASE address */
+ for (i = 0; i < cpuinfo->icache_size;
+ i += cpuinfo->icache_line)
+ __invalidate_icache(i);
+
+ __enable_icache();
+ local_irq_restore(flags);
+ }
+}
+
+void __flush_icache_range(unsigned long start, unsigned long end)
+{
+ unsigned int i;
+ unsigned flags;
+ unsigned int align;
+
+ if (cpuinfo->use_icache) {
+ /*
+ * No need to cover entire cache range,
+ * just cover cache footprint
+ */
+ end = min(start + cpuinfo->icache_size, end);
+ align = ~(cpuinfo->icache_line - 1);
+ start &= align; /* Make sure we are aligned */
+ /* Push end up to the next cache line */
+ end = ((end & align) + cpuinfo->icache_line);
+
+ local_irq_save(flags);
+ __disable_icache();
+
+ for (i = start; i < end; i += cpuinfo->icache_line)
+ __invalidate_icache(i);
+
+ __enable_icache();
+ local_irq_restore(flags);
+ }
+}
+
+void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+ __flush_icache_all();
+}
+
+void __flush_icache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long adr,
+ int len)
+{
+ __flush_icache_all();
+}
+
+void __flush_cache_sigtramp(unsigned long addr)
+{
+ __flush_icache_range(addr, addr + 8);
+}
+
+void __flush_dcache_all(void)
+{
+ unsigned int i;
+ unsigned flags;
+
+ if (cpuinfo->use_dcache) {
+ local_irq_save(flags);
+ __disable_dcache();
+
+ /*
+ * Just loop through cache size and invalidate,
+ * no need to add CACHE_BASE address
+ */
+ for (i = 0; i < cpuinfo->dcache_size;
+ i += cpuinfo->dcache_line)
+ __invalidate_dcache(i);
+
+ __enable_dcache();
+ local_irq_restore(flags);
+ }
+}
+
+void __flush_dcache_range(unsigned long start, unsigned long end)
+{
+ unsigned int i;
+ unsigned flags;
+ unsigned int align;
+
+ if (cpuinfo->use_dcache) {
+ /*
+ * No need to cover entire cache range,
+ * just cover cache footprint
+ */
+ end = min(start + cpuinfo->dcache_size, end);
+ align = ~(cpuinfo->dcache_line - 1);
+ start &= align; /* Make sure we are aligned */
+ /* Push end up to the next cache line */
+ end = ((end & align) + cpuinfo->dcache_line);
+ local_irq_save(flags);
+ __disable_dcache();
+
+ for (i = start; i < end; i += cpuinfo->dcache_line)
+ __invalidate_dcache(i);
+
+ __enable_dcache();
+ local_irq_restore(flags);
+ }
+}
+
+void __flush_dcache_page(struct vm_area_struct *vma, struct page *page)
+{
+ __flush_dcache_all();
+}
+
+void __flush_dcache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long adr,
+ int len)
+{
+ __flush_dcache_all();
+}
diff --git a/include/asm-microblaze/cache.h b/include/asm-microblaze/cache.h
new file mode 100644
index 0000000..e988152
--- /dev/null
+++ b/include/asm-microblaze/cache.h
@@ -0,0 +1,47 @@
+/*
+ * include/asm-microblaze/cache.h
+ *
+ * Cache operations
+ *
+ * Copyright (C) 2007 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_CACHE_H
+#define _MICROBLAZE_CACHE_H
+
+#include <asm/registers.h>
+#include <linux/autoconf.h>
+
+#ifndef L1_CACHE_BYTES
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES 4
+#endif
+
+void _enable_icache(void);
+void _disable_icache(void);
+void _invalidate_icache(unsigned int addr);
+
+#define __enable_icache() _enable_icache()
+#define __disable_icache() _disable_icache()
+#define __invalidate_icache(addr) _invalidate_icache(addr)
+
+void _enable_dcache(void);
+void _disable_dcache(void);
+void _invalidate_dcache(unsigned int addr);
+
+#define __enable_dcache() _enable_dcache()
+#define __disable_dcache() _disable_dcache()
+#define __invalidate_dcache(addr) _invalidate_dcache(addr)
+
+/* FIXME - I don't think this is right */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE)
+#endif
+
+#endif /* _MICROBLAZE_CACHE_H */
diff --git a/include/asm-microblaze/cacheflush.h b/include/asm-microblaze/cacheflush.h
new file mode 100644
index 0000000..3051690
--- /dev/null
+++ b/include/asm-microblaze/cacheflush.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-microblaze/cacheflush.h
+ *
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * based on v850 version which was
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _MICROBLAZE_CACHEFLUSH_H
+#define _MICROBLAZE_CACHEFLUSH_H
+
+/* Somebody depends on this; sigh... */
+#include <linux/mm.h>
+
+#define flush_cache_all() __flush_cache_all()
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_range(vma, start, end) __flush_cache_all()
+#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
+
+#define flush_dcache_range(start, end) __flush_dcache_range(start, end)
+#define flush_dcache_page(page) do { } while (0)
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+
+#define flush_icache_range(start, len) __flush_icache_range(start, len)
+#define flush_icache_page(vma, pg) do { } while (0)
+#define flush_icache_user_range(start, len) do { } while (0)
+
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* see arch/microblaze/kernel/cache.c */
+extern void __flush_icache_all(void);
+extern void __flush_icache_range(unsigned long start, unsigned long end);
+extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
+extern void __flush_icache_user_range(struct vm_area_struct *vma,
+ struct page *page,
+ unsigned long adr, int len);
+extern void __flush_cache_sigtramp(unsigned long addr);
+
+extern void __flush_dcache_all(void);
+extern void __flush_dcache_range(unsigned long start, unsigned long end);
+extern void __flush_dcache_page(struct vm_area_struct *vma, struct page *page);
+extern void __flush_dcache_user_range(struct vm_area_struct *vma,
+ struct page *page,
+ unsigned long adr, int len);
+
+extern inline void __flush_cache_all(void)
+{
+ __flush_icache_all();
+ __flush_dcache_all();
+}
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { memcpy(dst, src, len); \
+ flush_icache_user_range(vma, page, vaddr, len); \
+} while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy(dst, src, len)
+
+#endif /* _MICROBLAZE_CACHEFLUSH_H */
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* [PATCH 02/52] [microblaze] Makefiles for Microblaze cpu
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (49 preceding siblings ...)
2008-01-24 15:03 ` [PATCH 09/52] [microblaze] cache support monstr
@ 2008-01-24 15:05 ` monstr
2008-01-26 17:36 ` [PATCH 01/52] [microblaze] Kconfig patches Randy Dunlap
51 siblings, 0 replies; 67+ messages in thread
From: monstr @ 2008-01-24 15:05 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, sam
From: Michal Simek <monstr@monstr.eu>
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/Makefile | 66 +++++++++++++++++++++++++++++
arch/microblaze/boot/Makefile | 17 +++++++
arch/microblaze/kernel/Makefile | 14 ++++++
arch/microblaze/kernel/cpu/Makefile | 8 ++++
arch/microblaze/lib/Makefile | 5 ++
arch/microblaze/mm/Makefile | 5 ++
arch/microblaze/platform/Makefile | 3 +
arch/microblaze/platform/generic/Makefile | 5 ++
8 files changed, 123 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/Makefile
create mode 100644 arch/microblaze/boot/Makefile
create mode 100644 arch/microblaze/kernel/Makefile
create mode 100644 arch/microblaze/kernel/cpu/Makefile
create mode 100644 arch/microblaze/lib/Makefile
create mode 100644 arch/microblaze/mm/Makefile
create mode 100644 arch/microblaze/platform/Makefile
create mode 100644 arch/microblaze/platform/generic/Makefile
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
new file mode 100644
index 0000000..b5920e5
--- /dev/null
+++ b/arch/microblaze/Makefile
@@ -0,0 +1,66 @@
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# What CPU vesion are we building for, and crack it open
+# as major.minor.rev
+CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) )
+CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1)
+CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2)
+CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3)
+
+export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
+
+# Use cpu-related CONFIG_ vars to set compile options.
+
+# Work out HW multipler support. This is icky.
+# 1. Spartan2 has no HW multiplers.
+# 2. MicroBlaze v3.x always uses them, except in Spartan 2
+# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
+ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+ ifeq ($(CPU_MAJOR),3)
+ CPUFLAGS-1 += -mno-xl-soft-mul
+ else
+ # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support.
+ CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high
+ CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul
+ endif
+endif
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP) += -mxl-pattern-compare
+
+CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
+
+# The various CONFIG_XILINX cpu features options are integers 0/1/2...
+# rather than bools y/n
+CFLAGS += $(CPUFLAGS-1)
+CFLAGS += $(CPUFLAGS-2)
+
+# r31 holds current when in kernel mode
+CFLAGS += -ffixed-r31
+
+LDFLAGS_BLOB := --format binary --oformat elf32-microblaze
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+head-y := arch/microblaze/kernel/head.o
+libs-y += arch/microblaze/lib/ $(LIBGCC)
+core-y += arch/microblaze/kernel/ arch/microblaze/mm/
+# arch/microblaze/platform/
+
+
+boot := arch/$(ARCH)/boot
+
+all: linux.bin
+
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+linux.bin linux.bin.gz: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+
+define archhelp
+ echo '* linux.bin - Create raw binary'
+ echo ' linux.bin.gz - Create compressed raw binary'
+endef
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
new file mode 100644
index 0000000..844edf4
--- /dev/null
+++ b/arch/microblaze/boot/Makefile
@@ -0,0 +1,17 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+targets := linux.bin linux.bin.gz
+
+OBJCOPYFLAGS_linux.bin := -O binary
+
+$(obj)/linux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
+ $(call if_changed,gzip)
+ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+clean-kernel += linux.bin linux.bin.gz
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
new file mode 100644
index 0000000..26bef1a
--- /dev/null
+++ b/arch/microblaze/kernel/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile
+#
+
+extra-y := head.o vmlinux.lds
+
+obj-y += early_printk.o entry.o exceptions.o hack.o heartbeat.o \
+ hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
+ of_platform.o process.o prom.o prom_parse.o ptrace.o semaphore.o \
+ setup.o signal.o sys_microblaze.o time.o timer.o traps.o
+
+obj-y += cpu/
+
+obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile
new file mode 100644
index 0000000..20646e5
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/Makefile
@@ -0,0 +1,8 @@
+#
+# Build the appropriate CPU version support
+#
+
+EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
+ -DCPU_REV=$(CPU_REV)
+
+obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
new file mode 100644
index 0000000..fa18e83
--- /dev/null
+++ b/arch/microblaze/lib/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile
+#
+
+lib-y := checksum.o memcpy.o memmove.o memset.o uaccess.o
diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile
new file mode 100644
index 0000000..4f2f490
--- /dev/null
+++ b/arch/microblaze/mm/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile
+#
+
+obj-y := consistent.o init.o lmb.o
diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile
new file mode 100644
index 0000000..8797e83
--- /dev/null
+++ b/arch/microblaze/platform/Makefile
@@ -0,0 +1,3 @@
+#
+# Makefile for arch/microblaze/platform directory
+#
diff --git a/arch/microblaze/platform/generic/Makefile b/arch/microblaze/platform/generic/Makefile
new file mode 100644
index 0000000..ff5ef1e
--- /dev/null
+++ b/arch/microblaze/platform/generic/Makefile
@@ -0,0 +1,5 @@
+#
+# Empty Makefile to keep make clean happy
+#
+
+
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 01/52] [microblaze] Kconfig patches
2008-01-24 15:05 ` [PATCH 01/52] [microblaze] Kconfig patches monstr
` (50 preceding siblings ...)
2008-01-24 15:05 ` [PATCH 02/52] [microblaze] Makefiles for Microblaze cpu monstr
@ 2008-01-26 17:36 ` Randy Dunlap
2008-01-27 10:39 ` Michal Simek
2008-01-27 10:41 ` [PATCH 01/52] [microblaze] Kconfig patches v2 Michal Simek
51 siblings, 2 replies; 67+ messages in thread
From: Randy Dunlap @ 2008-01-26 17:36 UTC (permalink / raw)
To: monstr
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, sam
On Thu, 24 Jan 2008 16:05:18 +0100 monstr@monstr.eu wrote:
> From: Michal Simek <monstr@monstr.eu>
>
>
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> ---
> arch/microblaze/Kconfig | 160 +++++++++++++++++++++++++
> arch/microblaze/Kconfig.debug | 22 ++++
> arch/microblaze/platform/Kconfig.platform | 46 +++++++
> arch/microblaze/platform/generic/Kconfig.auto | 45 +++++++
> 4 files changed, 273 insertions(+), 0 deletions(-)
> create mode 100644 arch/microblaze/Kconfig
> create mode 100644 arch/microblaze/Kconfig.debug
> create mode 100644 arch/microblaze/platform/Kconfig.platform
> create mode 100644 arch/microblaze/platform/generic/Kconfig.auto
>
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> new file mode 100644
> index 0000000..6dbc069
> --- /dev/null
> +++ b/arch/microblaze/Kconfig
> @@ -0,0 +1,160 @@
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/config-language.txt.
It's kconfig-language.txt.
> +
> +mainmenu "Linux/Microblaze Kernel Configuration"
> +
> +config MICROBLAZE
> + bool
> + default y
The one-line form:
def_bool y
is preferred, just to be more concise, use less screen real estate...
Above and many times below.
> +config MMU
> + bool
> + default n
> +
> +config SWAP
> + bool
> + default n
> +
> +config RWSEM_GENERIC_SPINLOCK
> + bool
> + default y
> +
> +config RWSEM_XCHGADD_ALGORITHM
> + bool
> +
> +
> +config ARCH_HAS_ILOG2_U32
> + bool
> + default n
> +
> +config ARCH_HAS_ILOG2_U64
> + bool
> + default n
> +
> +config GENERIC_FIND_NEXT_BIT
> + bool
> + default y
> +
> +config GENERIC_HWEIGHT
> + bool
> + default y
> +
> +config GENERIC_HARDIRQS
> + bool
> + default y
> +
> +config GENERIC_IRQ_PROBE
> + bool
> + default y
> +
> +config GENERIC_CALIBRATE_DELAY
> + bool
> + default y
> +
> +config PCI
> + bool
> + default n
> +
> +config UID16
> + bool
> + default y
> +
> +config DEFCONFIG_LIST
> + string
> + default "arch/$ARCH/defconfig"
> +
> +source "init/Kconfig"
> +
> +source "arch/microblaze/platform/Kconfig.platform"
> +
> +menu "Processor type and features"
> +config PREEMPT
> + bool "Preemptible Kernel"
> + help
> + This option reduces the latency of the kernel when reacting to
> + real-time or interactive events by allowing a low priority process to
> + be preempted even if it is in kernel mode executing a system call.
> + This allows applications to run more reliably even when the system is
> + under load.
> +
> + Say Y here if you are building a kernel for a desktop, embedded
> + or real-time system. Say N if you are unsure.
> +
> +config PREEMPT_TIMES
> + bool "Collect preemption latency times"
> + depends on PREEMPT
> + help
> + Allow collection for preemption latency times.
> +
> +config XILINX_UNCACHED_SHADOW
> + bool "Are you using uncached shadow for RAM ?"
> + depends on MICROBLAZE
> + default y
> + help
> + This is needed to be able to allocate uncachable memory regions.
We don't seem to spell uncacheable consistently.
Kernel source tree:
uncachable - 27 times
uncacheable - 53 times
google:
uncachable - 11,900 hits
uncacheable - 26,700 hits
so I would use "uncacheable".
> + The feature requires the design to define the RAM memory controller window
> + to be twice as large as the actual physical memory.
> +
> +config LARGE_ALLOCS
> + bool "Allow allocating large blocks (> 1MB) of memory"
> + help
> + Allow the slab memory allocator to keep chains for very large
> + memory sizes - upto 32MB. You may need this if your system has
s/upto/up to/
> + a lot of RAM, and you need to able to allocate very large
> + contiguous chunks. If unsure, say N.
Please indent config symbol help text as indicated in
Documentation/CodingStyle: one tab + 2 spaces for each line of help text.
(Please check all help text.)
> +comment "Boot options"
> +
> +config CMDLINE
> + string "Default kernel command string"
> + default ""
> + help
> + On some architectures there is currently no way for the boot loader
> + to pass arguments to the kernel. For these architectures, you should
> + supply some command-line options at build time by entering them
> + here.
> +
> +config CMDLINE_FORCE
> + bool "Force default kernel command string"
> + help
> + Set this to have arguments from the default kernel command string
> + override those passed by the boot loader
End with period (".").
> +
> +config OF
> + bool
> + default y
> + help
> + Set this to turn on OF
End with period. Is this Open Firmware?
> +config OF_DEVICE
> + bool
> + default y
> + help
> + Set this to turn on OF
Ditto.
> +endmenu
> +
> +config APM_EMULATION
> + bool
> +
> +source "mm/Kconfig"
> +
> +menu "Exectuable file formats"
> +
> +source "fs/Kconfig.binfmt"
> +
> +endmenu
> +
> +source "net/Kconfig"
> +
> +source "drivers/Kconfig"
> +
> +source "fs/Kconfig"
> +
> +source "arch/microblaze/Kconfig.debug"
> +
> +source "security/Kconfig"
> +
> +source "crypto/Kconfig"
> +
> +source "lib/Kconfig"
> diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
> new file mode 100644
> index 0000000..1ccdd84
> --- /dev/null
> +++ b/arch/microblaze/Kconfig.debug
> @@ -0,0 +1,22 @@
> +menu "Kernel hacking"
> +
> +source "lib/Kconfig.debug"
> +
> +config EARLY_PRINTK
> + bool "EARLY_PRINTK"
> + default y
> +
> +config EARLY_PRINTK_UARTLITE_ADDRESS
> + hex "Physical address where UART Lite for early printk is mapped"
> + depends on EARLY_PRINTK
> + default "0x40600000"
> + help
> + Please enter physcal address where your uart lite is mapped
End with period. s/physcal/physical/
> +
> +config DEBUG_BOOTMEM
> + depends on DEBUG_KERNEL
> + bool "Debug BOOTMEM initialization"
> +
> +endmenu
> +
> +
> diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform
> new file mode 100644
> index 0000000..7b8eecb
> --- /dev/null
> +++ b/arch/microblaze/platform/Kconfig.platform
> @@ -0,0 +1,46 @@
> +#
> +# platform selection Kconfig menu for MicroBlaze targets
> +#
> +menu "Platform options"
> +choice
> + prompt "Platform"
> + default PLATFORM_MICROBLAZE_AUTO
> + help
> + Choose which hardware board/platform you are targeting
End with period.
> +
> +config PLATFORM_GENERIC
> + bool "Generic"
> + help
> + Choose this option for the Generic platform
end with period.
> +endchoice
> +
> +# This is stil a bit broken - disabling for now JW 20070504
s/stil/still/
> +config ALLOW_EDIT_AUTO
> + bool "Permit Display/edit of Kconfig.auto platform settings"
> + default n
> + help
> + Allows the editing of auto-generated platform settings from
> + the Kconfig.auto file. Obviously this does not change the
> + underlying hardware, so be very careful if you go editing
> + these settings.
> +
> + Also, if you enable this, and edit various Kconfig.auto
> + settings, YOUR CHANGES WILL BE LOST if you then disable it
> + again. You have been warned!
> +
> + If unsure, say no
End with period.
> +# Ok, the platform is chosen. Source the kconfig.auto to get all of the
> +# system settings.
> +# If user selected CONFIG_EDIT_AUTO, these will be rendered in gory detail
> +# and be able to be edited
> +comment "Automatic platform settings from Kconfig.auto"
> + depends on ALLOW_EDIT_AUTO
> +
> +if PLATFORM_GENERIC=y
> + source "arch/microblaze/platform/generic/Kconfig.auto"
> +endif
> +
> +endmenu
> +
> diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto
> new file mode 100644
> index 0000000..751369b
> --- /dev/null
> +++ b/arch/microblaze/platform/generic/Kconfig.auto
> @@ -0,0 +1,45 @@
> +#
> +# Platform Kconfig menu for Microblaze generic board
> +#
> +
> +config KERNEL_BASE_ADDR
> + hex "Physical address where Linux Kernel is"
> + default "0x44000000"
> + help
> + BASE Address for kernel
> +
> +config XILINX_ERAM_SIZE
> + hex "Size address of XILINX_RAM" if ALLOW_EDIT_AUTO && XILINX_UNCACHED_SHADOW
What is a "Size address"?
> + default 0x02000000
> +
> +comment "Definitions for MICROBLAZE0"
> + depends on ALLOW_EDIT_AUTO
> +
> +config XILINX_MICROBLAZE0_FAMILY
> + string "Targetted FPGA family" if ALLOW_EDIT_AUTO
> + default spartan3e
> +
> +config XILINX_MICROBLAZE0_HW_VER
> + string "Core version number" if ALLOW_EDIT_AUTO
> + default 5.00.c
> +
> +config XILINX_MICROBLAZE0_USE_MSR_INSTR
> + int "USE_MSR_INSTR" if ALLOW_EDIT_AUTO
> + default 1
> +
> +config XILINX_MICROBLAZE0_USE_BARREL
> + int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
> + default 1
These (above & below) look like booleans. If you really need a
range, config symbols can be specified as ranges. See
Documentation/kbuild/kconfig-language.txt.
> +config XILINX_MICROBLAZE0_USE_DIV
> + int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
> + default 1
> +
> +config XILINX_MICROBLAZE0_USE_HW_MUL
> + int "USE_HW_MUL range (0:1)" if ALLOW_EDIT_AUTO
> + default 1
> +
> +config XILINX_MICROBLAZE0_USE_FPU
> + int "USE_FPU range (0:1)" if ALLOW_EDIT_AUTO
> + default 0
> +
> --
---
~Randy
^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [PATCH 01/52] [microblaze] Kconfig patches
2008-01-26 17:36 ` [PATCH 01/52] [microblaze] Kconfig patches Randy Dunlap
@ 2008-01-27 10:39 ` Michal Simek
2008-01-27 10:41 ` [PATCH 01/52] [microblaze] Kconfig patches v2 Michal Simek
1 sibling, 0 replies; 67+ messages in thread
From: Michal Simek @ 2008-01-27 10:39 UTC (permalink / raw)
To: Randy Dunlap
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, sam
Hi Randy,
thanks for review. Comments are below.
>> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
>> new file mode 100644
>> index 0000000..6dbc069
>> --- /dev/null
>> +++ b/arch/microblaze/Kconfig
>> @@ -0,0 +1,160 @@
>> +# For a description of the syntax of this configuration file,
>> +# see Documentation/kbuild/config-language.txt.
>>
>
> It's kconfig-language.txt.
>
I fix it
>> +
>> +mainmenu "Linux/Microblaze Kernel Configuration"
>> +
>> +config MICROBLAZE
>> + bool
>> + default y
>>
>
> The one-line form:
> def_bool y
> is preferred, just to be more concise, use less screen real estate...
> Above and many times below.
>
fix.
>> +config MMU
>> + bool
>> + default n
>> +
>> +config SWAP
>> + bool
>> + default n
>> +
>> +config RWSEM_GENERIC_SPINLOCK
>> + bool
>> + default y
>> +
>> +config RWSEM_XCHGADD_ALGORITHM
>> + bool
>> +
>> +
>> +config ARCH_HAS_ILOG2_U32
>> + bool
>> + default n
>> +
>> +config ARCH_HAS_ILOG2_U64
>> + bool
>> + default n
>> +
>> +config GENERIC_FIND_NEXT_BIT
>> + bool
>> + default y
>> +
>> +config GENERIC_HWEIGHT
>> + bool
>> + default y
>> +
>> +config GENERIC_HARDIRQS
>> + bool
>> + default y
>> +
>> +config GENERIC_IRQ_PROBE
>> + bool
>> + default y
>> +
>> +config GENERIC_CALIBRATE_DELAY
>> + bool
>> + default y
>> +
>> +config PCI
>> + bool
>> + default n
>> +
>> +config UID16
>> + bool
>> + default y
>> +
>> +config DEFCONFIG_LIST
>> + string
>> + default "arch/$ARCH/defconfig"
>> +
>> +source "init/Kconfig"
>> +
>> +source "arch/microblaze/platform/Kconfig.platform"
>> +
>> +menu "Processor type and features"
>> +config PREEMPT
>> + bool "Preemptible Kernel"
>> + help
>> + This option reduces the latency of the kernel when reacting to
>> + real-time or interactive events by allowing a low priority process to
>> + be preempted even if it is in kernel mode executing a system call.
>> + This allows applications to run more reliably even when the system is
>> + under load.
>> +
>> + Say Y here if you are building a kernel for a desktop, embedded
>> + or real-time system. Say N if you are unsure.
>> +
>> +config PREEMPT_TIMES
>> + bool "Collect preemption latency times"
>> + depends on PREEMPT
>> + help
>> + Allow collection for preemption latency times.
>> +
>> +config XILINX_UNCACHED_SHADOW
>> + bool "Are you using uncached shadow for RAM ?"
>> + depends on MICROBLAZE
>> + default y
>> + help
>> + This is needed to be able to allocate uncachable memory regions.
>>
>
> We don't seem to spell uncacheable consistently.
>
> Kernel source tree:
> uncachable - 27 times
> uncacheable - 53 times
> google:
> uncachable - 11,900 hits
> uncacheable - 26,700 hits
>
> so I would use "uncacheable".
>
>
I don't know if is spelling correct. But I tried to find count of uncached
in kernel tree and a result is interesting. For me is not problem to
change it.
$ grep -rn "uncached" * | grep -v "microblaze" | grep "*" | wc -l
198
>> + The feature requires the design to define the RAM memory controller window
>> + to be twice as large as the actual physical memory.
>> +
>> +config LARGE_ALLOCS
>> + bool "Allow allocating large blocks (> 1MB) of memory"
>> + help
>> + Allow the slab memory allocator to keep chains for very large
>> + memory sizes - upto 32MB. You may need this if your system has
>>
>
> s/upto/up to/
>
fix.
>> + a lot of RAM, and you need to able to allocate very large
>> + contiguous chunks. If unsure, say N.
>>
>
> Please indent config symbol help text as indicated in
> Documentation/CodingStyle: one tab + 2 spaces for each line of help text.
> (Please check all help text.)
>
fix in all Kconfig files.
>> +comment "Boot options"
>> +
>> +config CMDLINE
>> + string "Default kernel command string"
>> + default ""
>> + help
>> + On some architectures there is currently no way for the boot loader
>> + to pass arguments to the kernel. For these architectures, you should
>> + supply some command-line options at build time by entering them
>> + here.
>> +
>> +config CMDLINE_FORCE
>> + bool "Force default kernel command string"
>> + help
>> + Set this to have arguments from the default kernel command string
>> + override those passed by the boot loader
>>
>
> End with period (".").
>
fix in all Kconfig files.
>> +
>> +config OF
>> + bool
>> + default y
>> + help
>> + Set this to turn on OF
>>
>
> End with period. Is this Open Firmware?
>
>
>> +config OF_DEVICE
>> + bool
>> + default y
>> + help
>> + Set this to turn on OF
>>
>
> Ditto.
>
Yes. Microblaze architecture use Open Firmware files. I set to this
value with def_boot y without help part.
>> diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
>> new file mode 100644
>> index 0000000..1ccdd84
>> --- /dev/null
>> +++ b/arch/microblaze/Kconfig.debug
>> @@ -0,0 +1,22 @@
>> +menu "Kernel hacking"
>> +
>> +source "lib/Kconfig.debug"
>> +
>> +config EARLY_PRINTK
>> + bool "EARLY_PRINTK"
>> + default y
>> +
>> +config EARLY_PRINTK_UARTLITE_ADDRESS
>> + hex "Physical address where UART Lite for early printk is mapped"
>> + depends on EARLY_PRINTK
>> + default "0x40600000"
>> + help
>> + Please enter physcal address where your uart lite is mapped
>>
>
> End with period. s/physcal/physical/
>
fix + all period faults.
>> +endchoice
>> +
>> +# This is stil a bit broken - disabling for now JW 20070504
>>
>
> s/stil/still/
>
fix
>> diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto
>> new file mode 100644
>> index 0000000..751369b
>> --- /dev/null
>> +++ b/arch/microblaze/platform/generic/Kconfig.auto
>> @@ -0,0 +1,45 @@
>> +#
>> +# Platform Kconfig menu for Microblaze generic board
>> +#
>> +
>> +config KERNEL_BASE_ADDR
>> + hex "Physical address where Linux Kernel is"
>> + default "0x44000000"
>> + help
>> + BASE Address for kernel
>> +
>> +config XILINX_ERAM_SIZE
>> + hex "Size address of XILINX_RAM" if ALLOW_EDIT_AUTO && XILINX_UNCACHED_SHADOW
>>
>
> What is a "Size address"?
>
Size address is physical size of main memory - fix.
>> + default 0x02000000
>> +
>> +comment "Definitions for MICROBLAZE0"
>> + depends on ALLOW_EDIT_AUTO
>> +
>> +config XILINX_MICROBLAZE0_FAMILY
>> + string "Targetted FPGA family" if ALLOW_EDIT_AUTO
>> + default spartan3e
>> +
>> +config XILINX_MICROBLAZE0_HW_VER
>> + string "Core version number" if ALLOW_EDIT_AUTO
>> + default 5.00.c
>> +
>> +config XILINX_MICROBLAZE0_USE_MSR_INSTR
>> + int "USE_MSR_INSTR" if ALLOW_EDIT_AUTO
>> + default 1
>> +
>> +config XILINX_MICROBLAZE0_USE_BARREL
>> + int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
>> + default 1
>>
>
> These (above & below) look like booleans. If you really need a
> range, config symbols can be specified as ranges. See
> Documentation/kbuild/kconfig-language.txt.
>
Fix is with range property.
>> +config XILINX_MICROBLAZE0_USE_DIV
>> + int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
>> + default 1
>> +
>> +config XILINX_MICROBLAZE0_USE_HW_MUL
>> + int "USE_HW_MUL range (0:1)" if ALLOW_EDIT_AUTO
>> + default 1
>> +
>> +config XILINX_MICROBLAZE0_USE_FPU
>> + int "USE_FPU range (0:1)" if ALLOW_EDIT_AUTO
>> + default 0
>> +
>> --
>>
>
> ---
> ~Randy
Regards,
Michal Simek
^ permalink raw reply [flat|nested] 67+ messages in thread
* [PATCH 01/52] [microblaze] Kconfig patches v2
2008-01-26 17:36 ` [PATCH 01/52] [microblaze] Kconfig patches Randy Dunlap
2008-01-27 10:39 ` Michal Simek
@ 2008-01-27 10:41 ` Michal Simek
2008-01-27 17:15 ` Randy Dunlap
1 sibling, 1 reply; 67+ messages in thread
From: Michal Simek @ 2008-01-27 10:41 UTC (permalink / raw)
To: Randy Dunlap
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, sam
From cd9e680aa7a732c1ff1188a22f2a0950f5d24e3b Mon Sep 17 00:00:00 2001
Message-Id:
<cd9e680aa7a732c1ff1188a22f2a0950f5d24e3b.1201429312.git.monstr@monstr.eu>
From: Michal Simek <monstr@monstr.eu>
Date: Sun, 27 Jan 2008 11:21:34 +0100
Subject: [PATCH 1/1] [microblaze] Kconfig patches v2
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
arch/microblaze/Kconfig | 140
+++++++++++++++++++++++++
arch/microblaze/Kconfig.debug | 22 ++++
arch/microblaze/platform/Kconfig.platform | 48 +++++++++
arch/microblaze/platform/generic/Kconfig.auto | 51 +++++++++
4 files changed, 261 insertions(+), 0 deletions(-)
create mode 100644 arch/microblaze/Kconfig
create mode 100644 arch/microblaze/Kconfig.debug
create mode 100644 arch/microblaze/platform/Kconfig.platform
create mode 100644 arch/microblaze/platform/generic/Kconfig.auto
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
new file mode 100644
index 0000000..3ef7be5
--- /dev/null
+++ b/arch/microblaze/Kconfig
@@ -0,0 +1,140 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+mainmenu "Linux/Microblaze Kernel Configuration"
+
+config MICROBLAZE
+ def_bool y
+
+config MMU
+ def_bool n
+
+config SWAP
+ def_bool n
+
+config RWSEM_GENERIC_SPINLOCK
+ def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config ARCH_HAS_ILOG2_U32
+ def_bool n
+
+config ARCH_HAS_ILOG2_U64
+ def_bool n
+
+config GENERIC_FIND_NEXT_BIT
+ def_bool y
+
+config GENERIC_HWEIGHT
+ def_bool y
+
+config GENERIC_HARDIRQS
+ def_bool y
+
+config GENERIC_IRQ_PROBE
+ def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+ def_bool y
+
+config PCI
+ def_bool n
+
+config UID16
+ def_bool y
+
+config DEFCONFIG_LIST
+ string
+ default "arch/$ARCH/defconfig"
+
+source "init/Kconfig"
+
+source "arch/microblaze/platform/Kconfig.platform"
+
+menu "Processor type and features"
+config PREEMPT
+ bool "Preemptible Kernel"
+ help
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ This allows applications to run more reliably even when the system is
+ under load.
+
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
+
+config PREEMPT_TIMES
+ bool "Collect preemption latency times"
+ depends on PREEMPT
+ help
+ Allow collection for preemption latency times.
+
+config XILINX_UNCACHED_SHADOW
+ bool "Are you using uncached shadow for RAM ?"
+ depends on MICROBLAZE
+ default y
+ help
+ This is needed to be able to allocate uncachable memory regions.
+ The feature requires the design to define the RAM memory
controller window
+ to be twice as large as the actual physical memory.
+
+config LARGE_ALLOCS
+ bool "Allow allocating large blocks (> 1MB) of memory"
+ help
+ Allow the slab memory allocator to keep chains for very large
+ memory sizes - up to 32MB. You may need this if your system has
+ a lot of RAM, and you need to able to allocate very large
+ contiguous chunks. If unsure, say N.
+
+comment "Boot options"
+
+config CMDLINE
+ string "Default kernel command string"
+ default ""
+ help
+ On some architectures there is currently no way for the boot loader
+ to pass arguments to the kernel. For these architectures, you should
+ supply some command-line options at build time by entering them
+ here.
+
+config CMDLINE_FORCE
+ bool "Force default kernel command string"
+ help
+ Set this to have arguments from the default kernel command string
+ override those passed by the boot loader.
+
+config OF
+ def_bool y
+
+config OF_DEVICE
+ def_bool y
+
+endmenu
+
+config APM_EMULATION
+ bool
+
+source "mm/Kconfig"
+
+menu "Exectuable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/microblaze/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
new file mode 100644
index 0000000..f75d3e8
--- /dev/null
+++ b/arch/microblaze/Kconfig.debug
@@ -0,0 +1,22 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+ def_bool y
+
+config EARLY_PRINTK_UARTLITE_ADDRESS
+ hex "Physical address where UART Lite for early printk is mapped"
+ depends on EARLY_PRINTK
+ default "0x40600000"
+ help
+ Please enter physical address where your uart lite is mapped.
+
+config DEBUG_BOOTMEM
+ depends on DEBUG_KERNEL
+ bool "Debug BOOTMEM initialization"
+
+endmenu
diff --git a/arch/microblaze/platform/Kconfig.platform
b/arch/microblaze/platform/Kconfig.platform
new file mode 100644
index 0000000..6733dc9
--- /dev/null
+++ b/arch/microblaze/platform/Kconfig.platform
@@ -0,0 +1,48 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Platform selection Kconfig menu for MicroBlaze targets
+#
+
+menu "Platform options"
+choice
+ prompt "Platform"
+ default PLATFORM_MICROBLAZE_AUTO
+ help
+ Choose which hardware board/platform you are targeting.
+
+config PLATFORM_GENERIC
+ bool "Generic"
+ help
+ Choose this option for the Generic platform.
+
+endchoice
+
+# This is still a bit broken - disabling for now JW 20070504
+config ALLOW_EDIT_AUTO
+ bool "Permit Display/edit of Kconfig.auto platform settings"
+ default n
+ help
+ Allows the editing of auto-generated platform settings from
+ the Kconfig.auto file. Obviously this does not change the
+ underlying hardware, so be very careful if you go editing
+ these settings.
+
+ Also, if you enable this, and edit various Kconfig.auto
+ settings, YOUR CHANGES WILL BE LOST if you then disable it
+ again. You have been warned!
+
+ If unsure, say no.
+
+# Ok, the platform is chosen. Source the kconfig.auto to get all of the
+# system settings.
+# If user selected CONFIG_EDIT_AUTO, these will be rendered in gory detail
+# and be able to be edited
+comment "Automatic platform settings from Kconfig.auto"
+ depends on ALLOW_EDIT_AUTO
+
+if PLATFORM_GENERIC=y
+ source "arch/microblaze/platform/generic/Kconfig.auto"
+endif
+
+endmenu
diff --git a/arch/microblaze/platform/generic/Kconfig.auto
b/arch/microblaze/platform/generic/Kconfig.auto
new file mode 100644
index 0000000..1022a1a
--- /dev/null
+++ b/arch/microblaze/platform/generic/Kconfig.auto
@@ -0,0 +1,51 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Platform Kconfig menu for Microblaze generic board
+#
+
+config KERNEL_BASE_ADDR
+ hex "Physical address where Linux Kernel is"
+ default "0x44000000"
+ help
+ BASE Address for kernel
+
+config XILINX_ERAM_SIZE
+ hex "Memory size of XILINX_RAM" if XILINX_UNCACHED_SHADOW
+ default 0x02000000
+
+comment "Definitions for MICROBLAZE0"
+ depends on ALLOW_EDIT_AUTO
+
+config XILINX_MICROBLAZE0_FAMILY
+ string "Targetted FPGA family" if ALLOW_EDIT_AUTO
+ default spartan3e
+
+config XILINX_MICROBLAZE0_HW_VER
+ string "Core version number" if ALLOW_EDIT_AUTO
+ default 5.00.c
+
+config XILINX_MICROBLAZE0_USE_MSR_INSTR
+ int "USE_MSR_INSTR" if ALLOW_EDIT_AUTO
+ default 1
+ range 0 1
+
+config XILINX_MICROBLAZE0_USE_BARREL
+ int "USE_BARREL" if ALLOW_EDIT_AUTO
+ default 1
+ range 0 1
+
+config XILINX_MICROBLAZE0_USE_DIV
+ int "USE_DIV" if ALLOW_EDIT_AUTO
+ default 1
+ range 0 1
+
+config XILINX_MICROBLAZE0_USE_HW_MUL
+ int "USE_HW_MUL" if ALLOW_EDIT_AUTO
+ default 1
+ range 0 2
+
+config XILINX_MICROBLAZE0_USE_FPU
+ int "USE_FPU" if ALLOW_EDIT_AUTO
+ default 0
+ range 0 1
--
1.5.4.rc4.14.g6fc74
^ permalink raw reply related [flat|nested] 67+ messages in thread
* Re: [PATCH 01/52] [microblaze] Kconfig patches v2
2008-01-27 10:41 ` [PATCH 01/52] [microblaze] Kconfig patches v2 Michal Simek
@ 2008-01-27 17:15 ` Randy Dunlap
0 siblings, 0 replies; 67+ messages in thread
From: Randy Dunlap @ 2008-01-27 17:15 UTC (permalink / raw)
To: Michal Simek
Cc: linux-kernel, stephen.neuendorffer, john.williams,
microblaze-uclinux, sam
On Sun, 27 Jan 2008 11:41:01 +0100 Michal Simek wrote:
> From cd9e680aa7a732c1ff1188a22f2a0950f5d24e3b Mon Sep 17 00:00:00 2001
> Message-Id:
> <cd9e680aa7a732c1ff1188a22f2a0950f5d24e3b.1201429312.git.monstr@monstr.eu>
> From: Michal Simek <monstr@monstr.eu>
> Date: Sun, 27 Jan 2008 11:21:34 +0100
> Subject: [PATCH 1/1] [microblaze] Kconfig patches v2
>
>
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> ---
> arch/microblaze/Kconfig | 140
> +++++++++++++++++++++++++
> arch/microblaze/Kconfig.debug | 22 ++++
> arch/microblaze/platform/Kconfig.platform | 48 +++++++++
> arch/microblaze/platform/generic/Kconfig.auto | 51 +++++++++
> 4 files changed, 261 insertions(+), 0 deletions(-)
> create mode 100644 arch/microblaze/Kconfig
> create mode 100644 arch/microblaze/Kconfig.debug
> create mode 100644 arch/microblaze/platform/Kconfig.platform
> create mode 100644 arch/microblaze/platform/generic/Kconfig.auto
>
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> new file mode 100644
> index 0000000..3ef7be5
> --- /dev/null
> +++ b/arch/microblaze/Kconfig
> @@ -0,0 +1,140 @@
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +
> +mainmenu "Linux/Microblaze Kernel Configuration"
> +
> +config MICROBLAZE
> + def_bool y
> +
> +config MMU
> + def_bool n
> +
> +config SWAP
> + def_bool n
> +
> +config RWSEM_GENERIC_SPINLOCK
> + def_bool y
> +
> +config RWSEM_XCHGADD_ALGORITHM
> + bool
> +
> +config ARCH_HAS_ILOG2_U32
> + def_bool n
> +
> +config ARCH_HAS_ILOG2_U64
> + def_bool n
> +
> +config GENERIC_FIND_NEXT_BIT
> + def_bool y
> +
> +config GENERIC_HWEIGHT
> + def_bool y
> +
> +config GENERIC_HARDIRQS
> + def_bool y
> +
> +config GENERIC_IRQ_PROBE
> + def_bool y
> +
> +config GENERIC_CALIBRATE_DELAY
> + def_bool y
> +
> +config PCI
> + def_bool n
> +
> +config UID16
> + def_bool y
> +
> +config DEFCONFIG_LIST
> + string
> + default "arch/$ARCH/defconfig"
> +
> +source "init/Kconfig"
> +
> +source "arch/microblaze/platform/Kconfig.platform"
> +
> +menu "Processor type and features"
> +config PREEMPT
> + bool "Preemptible Kernel"
> + help
> + This option reduces the latency of the kernel when reacting to
> + real-time or interactive events by allowing a low priority process to
> + be preempted even if it is in kernel mode executing a system call.
> + This allows applications to run more reliably even when the system is
> + under load.
> +
> + Say Y here if you are building a kernel for a desktop, embedded
> + or real-time system. Say N if you are unsure.
> +
> +config PREEMPT_TIMES
> + bool "Collect preemption latency times"
> + depends on PREEMPT
> + help
> + Allow collection for preemption latency times.
> +
> +config XILINX_UNCACHED_SHADOW
> + bool "Are you using uncached shadow for RAM ?"
> + depends on MICROBLAZE
> + default y
> + help
> + This is needed to be able to allocate uncachable memory regions.
> + The feature requires the design to define the RAM memory
> controller window
> + to be twice as large as the actual physical memory.
Hi,
In my MUA, the "controller window" text is on a line by itself
but it shouldn't be. (http://lkml.org/lkml/2008/1/27/85
shows the same condition.)
I guess that Thunderbird is doing this for you (sadly).
Please see if Documentation/email-clients.txt can help you with
this.
A larger issue is that I don't see any tabs in the patch.
Kconfig reserved words (like bool and def_bool) should be indented
by 1 tab, and help text by 1 tab + 2 spaces.
I suppose that Thunderbird could have done this also. :(
> +
> +config LARGE_ALLOCS
> + bool "Allow allocating large blocks (> 1MB) of memory"
> + help
> + Allow the slab memory allocator to keep chains for very large
> + memory sizes - up to 32MB. You may need this if your system has
> + a lot of RAM, and you need to able to allocate very large
> + contiguous chunks. If unsure, say N.
> +
> +comment "Boot options"
> +
> +config CMDLINE
> + string "Default kernel command string"
> + default ""
> + help
> + On some architectures there is currently no way for the boot loader
> + to pass arguments to the kernel. For these architectures, you should
> + supply some command-line options at build time by entering them
> + here.
> +
> +config CMDLINE_FORCE
> + bool "Force default kernel command string"
> + help
> + Set this to have arguments from the default kernel command string
> + override those passed by the boot loader.
> +
> +config OF
> + def_bool y
> +
> +config OF_DEVICE
> + def_bool y
> +
> +endmenu
> +
> +config APM_EMULATION
> + bool
> +
> +source "mm/Kconfig"
> +
> +menu "Exectuable file formats"
> +
> +source "fs/Kconfig.binfmt"
> +
> +endmenu
> +
> +source "net/Kconfig"
> +
> +source "drivers/Kconfig"
> +
> +source "fs/Kconfig"
> +
> +source "arch/microblaze/Kconfig.debug"
> +
> +source "security/Kconfig"
> +
> +source "crypto/Kconfig"
> +
> +source "lib/Kconfig"
> diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
> new file mode 100644
> index 0000000..f75d3e8
> --- /dev/null
> +++ b/arch/microblaze/Kconfig.debug
> @@ -0,0 +1,22 @@
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +
> +menu "Kernel hacking"
> +
> +source "lib/Kconfig.debug"
> +
> +config EARLY_PRINTK
> + def_bool y
> +
> +config EARLY_PRINTK_UARTLITE_ADDRESS
> + hex "Physical address where UART Lite for early printk is mapped"
> + depends on EARLY_PRINTK
> + default "0x40600000"
> + help
> + Please enter physical address where your uart lite is mapped.
> +
> +config DEBUG_BOOTMEM
> + depends on DEBUG_KERNEL
> + bool "Debug BOOTMEM initialization"
> +
> +endmenu
> diff --git a/arch/microblaze/platform/Kconfig.platform
> b/arch/microblaze/platform/Kconfig.platform
> new file mode 100644
> index 0000000..6733dc9
> --- /dev/null
> +++ b/arch/microblaze/platform/Kconfig.platform
> @@ -0,0 +1,48 @@
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +#
> +# Platform selection Kconfig menu for MicroBlaze targets
> +#
> +
> +menu "Platform options"
> +choice
> + prompt "Platform"
> + default PLATFORM_MICROBLAZE_AUTO
> + help
> + Choose which hardware board/platform you are targeting.
> +
> +config PLATFORM_GENERIC
> + bool "Generic"
> + help
> + Choose this option for the Generic platform.
> +
> +endchoice
> +
> +# This is still a bit broken - disabling for now JW 20070504
> +config ALLOW_EDIT_AUTO
> + bool "Permit Display/edit of Kconfig.auto platform settings"
> + default n
> + help
> + Allows the editing of auto-generated platform settings from
> + the Kconfig.auto file. Obviously this does not change the
> + underlying hardware, so be very careful if you go editing
> + these settings.
> +
> + Also, if you enable this, and edit various Kconfig.auto
> + settings, YOUR CHANGES WILL BE LOST if you then disable it
> + again. You have been warned!
> +
> + If unsure, say no.
> +
> +# Ok, the platform is chosen. Source the kconfig.auto to get all of the
> +# system settings.
> +# If user selected CONFIG_EDIT_AUTO, these will be rendered in gory detail
> +# and be able to be edited
> +comment "Automatic platform settings from Kconfig.auto"
> + depends on ALLOW_EDIT_AUTO
> +
> +if PLATFORM_GENERIC=y
> + source "arch/microblaze/platform/generic/Kconfig.auto"
> +endif
> +
> +endmenu
> diff --git a/arch/microblaze/platform/generic/Kconfig.auto
> b/arch/microblaze/platform/generic/Kconfig.auto
> new file mode 100644
> index 0000000..1022a1a
> --- /dev/null
> +++ b/arch/microblaze/platform/generic/Kconfig.auto
> @@ -0,0 +1,51 @@
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +#
> +# Platform Kconfig menu for Microblaze generic board
> +#
> +
> +config KERNEL_BASE_ADDR
> + hex "Physical address where Linux Kernel is"
> + default "0x44000000"
> + help
> + BASE Address for kernel
> +
> +config XILINX_ERAM_SIZE
> + hex "Memory size of XILINX_RAM" if XILINX_UNCACHED_SHADOW
> + default 0x02000000
> +
> +comment "Definitions for MICROBLAZE0"
> + depends on ALLOW_EDIT_AUTO
> +
> +config XILINX_MICROBLAZE0_FAMILY
> + string "Targetted FPGA family" if ALLOW_EDIT_AUTO
> + default spartan3e
> +
> +config XILINX_MICROBLAZE0_HW_VER
> + string "Core version number" if ALLOW_EDIT_AUTO
> + default 5.00.c
> +
> +config XILINX_MICROBLAZE0_USE_MSR_INSTR
> + int "USE_MSR_INSTR" if ALLOW_EDIT_AUTO
> + default 1
> + range 0 1
> +
> +config XILINX_MICROBLAZE0_USE_BARREL
> + int "USE_BARREL" if ALLOW_EDIT_AUTO
> + default 1
> + range 0 1
> +
> +config XILINX_MICROBLAZE0_USE_DIV
> + int "USE_DIV" if ALLOW_EDIT_AUTO
> + default 1
> + range 0 1
> +
> +config XILINX_MICROBLAZE0_USE_HW_MUL
> + int "USE_HW_MUL" if ALLOW_EDIT_AUTO
> + default 1
> + range 0 2
> +
> +config XILINX_MICROBLAZE0_USE_FPU
> + int "USE_FPU" if ALLOW_EDIT_AUTO
> + default 0
> + range 0 1
> --
---
~Randy
^ permalink raw reply [flat|nested] 67+ messages in thread