Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32: (40 commits)
  unicore32: rewrite arch-specific tlb.h to use asm-generic version
  unicore32: modify io_p2v and io_v2p macros, and adjust PKUNITY_mmio_BASEs
  unicore32: replace unicore32-specific iomap functions with generic lib implementation
  unicore32 machine related: add frame buffer driver for pkunity-v3 soc
  unicore32 machine related files: add i2c bus drivers for pkunity-v3 soc
  unicore32 io: redefine __REG(x) and re-use readl/writel funcs
  unicore32 i8042 upgrade and bugfix: adjust resource request region type
  unicore32 upgrade to v2.6.38-rc5: add one more paramter for pte_alloc_map call
  unicore32 i8042: adjust io funcs of i8042-unicore32io.h
  unicore32: rename PKUNITY_IOSPACE_BASE to PKUNITY_MMIO_BASE
  unicore32: modify function names and parameters for irq_chips
  unicore32: remove unused lines in arch/unicore32/include/asm/irq.h
  unicore32 time.c: change calculate method for clock_event_device
  unicore32: ADD MAINTAINER for unicore32 architecture
  unicore32 machine related files: ps2 driver
  unicore32 machine related files: pci bus handling
  unicore32 machine related files: hardware registers
  unicore32 machine related files: core files
  unicore32 additional architecture files: boot process
  unicore32 additional architecture files: low-level lib: misc
  ...

Acked-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Linus Torvalds 2011-03-17 10:11:25 -07:00
commit 7b7adc4a01
163 changed files with 19408 additions and 17 deletions

View File

@ -4907,6 +4907,15 @@ S: Maintained
F: drivers/block/pktcdvd.c
F: include/linux/pktcdvd.h
PKUNITY SOC DRIVERS
M: Guan Xuetao <gxt@mprc.pku.edu.cn>
W: http://mprc.pku.edu.cn/~guanxuetao/linux
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
F: drivers/input/serio/i8042-unicore32io.h
F: drivers/i2c/busses/i2c-puv3.c
F: drivers/video/fb-puv3.c
PMC SIERRA MaxRAID DRIVER
M: Anil Ravindranath <anil_ravindranath@pmc-sierra.com>
L: linux-scsi@vger.kernel.org
@ -6270,6 +6279,13 @@ F: drivers/uwb/
F: include/linux/uwb.h
F: include/linux/uwb/
UNICORE32 ARCHITECTURE:
M: Guan Xuetao <gxt@mprc.pku.edu.cn>
W: http://mprc.pku.edu.cn/~guanxuetao/linux
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/epip/linux-2.6-unicore32.git
F: arch/unicore32/
UNIFDEF
M: Tony Finch <dot@dotat.at>
W: http://dotat.at/prog/unifdef

21
arch/unicore32/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
#
# Generated include files
#
include/generated
#
# Generated ld script file
#
kernel/vmlinux.lds
#
# Generated images in boot
#
boot/Image
boot/zImage
boot/uImage
#
# Generated files in boot/compressed
#
boot/compressed/piggy.S
boot/compressed/piggy.gzip
boot/compressed/vmlinux
boot/compressed/vmlinux.lds

275
arch/unicore32/Kconfig Normal file
View File

@ -0,0 +1,275 @@
config UNICORE32
def_bool y
select HAVE_MEMBLOCK
select HAVE_GENERIC_DMA_COHERENT
select HAVE_GENERIC_HARDIRQS
select HAVE_DMA_ATTRS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZO
select HAVE_KERNEL_LZMA
select GENERIC_FIND_FIRST_BIT
select GENERIC_IRQ_PROBE
select GENERIC_HARDIRQS_NO_DEPRECATED
select ARCH_WANT_FRAME_POINTERS
help
UniCore-32 is 32-bit Instruction Set Architecture,
including a series of low-power-consumption RISC chip
designs licensed by PKUnity Ltd.
Please see web page at <http://www.pkunity.com/>.
config HAVE_PWM
bool
config GENERIC_GPIO
def_bool y
config GENERIC_CLOCKEVENTS
bool
config GENERIC_CSUM
def_bool y
config GENERIC_IOMAP
def_bool y
config NO_IOPORT
bool
config STACKTRACE_SUPPORT
def_bool y
config HAVE_LATENCYTOP_SUPPORT
def_bool y
config LOCKDEP_SUPPORT
def_bool y
config RWSEM_GENERIC_SPINLOCK
def_bool y
config RWSEM_XCHGADD_ALGORITHM
bool
config ARCH_HAS_ILOG2_U32
bool
config ARCH_HAS_ILOG2_U64
bool
config ARCH_HAS_CPUFREQ
bool
config GENERIC_HWEIGHT
def_bool y
config GENERIC_CALIBRATE_DELAY
def_bool y
config ARCH_MAY_HAVE_PC_FDC
bool
config NEED_DMA_MAP_STATE
def_bool y
source "init/Kconfig"
source "kernel/Kconfig.freezer"
menu "System Type"
config MMU
def_bool y
config ARCH_FPGA
bool
config ARCH_PUV3
def_bool y
select CPU_UCV2
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
# CONFIGs for ARCH_PUV3
if ARCH_PUV3
choice
prompt "Board Selection"
default PUV3_DB0913
config PUV3_FPGA_DLX200
select ARCH_FPGA
bool "FPGA board"
config PUV3_DB0913
bool "DEBUG board (0913)"
config PUV3_NB0916
bool "NetBook board (0916)"
select HAVE_PWM
config PUV3_SMW0919
bool "Security Mini-Workstation board (0919)"
endchoice
config PUV3_PM
def_bool y if !ARCH_FPGA
endif
source "arch/unicore32/mm/Kconfig"
comment "Floating poing support"
config UNICORE_FPU_F64
def_bool y if !ARCH_FPGA
endmenu
menu "Bus support"
config PCI
bool "PCI Support"
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N.
source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
endmenu
menu "Kernel Features"
source "kernel/time/Kconfig"
source "kernel/Kconfig.preempt"
source "kernel/Kconfig.hz"
source "mm/Kconfig"
config LEDS
def_bool y
depends on GENERIC_GPIO
config ALIGNMENT_TRAP
def_bool y
help
Unicore processors can not fetch/store information which is not
naturally aligned on the bus, i.e., a 4 byte fetch must start at an
address divisible by 4. On 32-bit Unicore processors, these non-aligned
fetch/store instructions will be emulated in software if you say
here, which has a severe performance impact. This is necessary for
correct operation of some network protocols. With an IP-only
configuration it is safe to say N, otherwise say Y.
endmenu
menu "Boot options"
config CMDLINE
string "Default kernel command string"
default ""
config CMDLINE_FORCE
bool "Always use the default kernel command string"
depends on CMDLINE != ""
help
Always use the default kernel command string, even if the boot
loader passes other arguments to the kernel.
This is useful if you cannot or don't want to change the
command-line options your boot loader passes to the kernel.
If unsure, say N.
endmenu
menu "Userspace binary formats"
source "fs/Kconfig.binfmt"
endmenu
menu "Power management options"
source "kernel/power/Kconfig"
if ARCH_HAS_CPUFREQ
source "drivers/cpufreq/Kconfig"
endif
config ARCH_SUSPEND_POSSIBLE
def_bool y if !ARCH_FPGA
config ARCH_HIBERNATION_POSSIBLE
def_bool y if !ARCH_FPGA
endmenu
source "net/Kconfig"
if ARCH_PUV3
config PUV3_GPIO
bool
depends on !ARCH_FPGA
select GENERIC_GPIO
select GPIO_SYSFS if EXPERIMENTAL
default y
config PUV3_PWM
tristate
default BACKLIGHT_PWM
help
Enable support for NB0916 PWM controllers
config PUV3_RTC
tristate "PKUnity v3 RTC Support"
depends on !ARCH_FPGA
if PUV3_NB0916
menu "PKUnity NetBook-0916 Features"
config I2C_BATTERY_BQ27200
tristate "I2C Battery BQ27200 Support"
select PUV3_I2C
select POWER_SUPPLY
select BATTERY_BQ27x00
config I2C_EEPROM_AT24
tristate "I2C EEPROMs AT24 support"
select PUV3_I2C
select MISC_DEVICES
select EEPROM_AT24
config LCD_BACKLIGHT
tristate "LCD Backlight support"
select BACKLIGHT_LCD_SUPPORT
select BACKLIGHT_PWM
endmenu
endif
endif
source "drivers/Kconfig"
source "fs/Kconfig"
source "arch/unicore32/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"

View File

@ -0,0 +1,68 @@
menu "Kernel hacking"
source "lib/Kconfig.debug"
config STRICT_DEVMEM
bool "Filter access to /dev/mem"
depends on MMU
---help---
If this option is disabled, you allow userspace (root) access to all
of memory, including kernel and userspace memory. Accidental
access to this is obviously disastrous, but specific access can
be used by people debugging the kernel.
If this option is switched on, the /dev/mem file only allows
userspace access to memory mapped peripherals.
If in doubt, say Y.
config EARLY_PRINTK
def_bool DEBUG_OCD
help
Write kernel log output directly into the ocd or to a serial port.
This is useful for kernel debugging when your machine crashes very
early before the console code is initialized. For normal operation
it is not recommended because it looks ugly and doesn't cooperate
with klogd/syslogd or the X server. You should normally N here,
unless you want to debug such a crash.
config DEBUG_STACK_USAGE
bool "Enable stack utilization instrumentation"
depends on DEBUG_KERNEL
help
Enables the display of the minimum amount of free stack which each
task has ever had available in the sysrq-T output.
# These options are only for real kernel hackers who want to get their hands dirty.
config DEBUG_LL
bool "Kernel low-level debugging functions"
depends on DEBUG_KERNEL
help
Say Y here to include definitions of printascii, printch, printhex
in the kernel. This is helpful if you are debugging code that
executes before the console is initialized.
config DEBUG_OCD
bool "Kernel low-level debugging via On-Chip-Debugger"
depends on DEBUG_LL
default y
help
Say Y here if you want the debug print routines to direct their
output to the UniCore On-Chip-Debugger channel using CP #1.
config DEBUG_OCD_BREAKPOINT
bool "Breakpoint support via On-Chip-Debugger"
depends on DEBUG_OCD
config DEBUG_UART
int "Kernel low-level debugging messages via serial port"
depends on DEBUG_LL
range 0 1
default "0"
help
Choice for UART for kernel low-level using PKUnity UARTS,
should be between zero and one. The port must have been
initialised by the boot-loader before use.
endmenu

95
arch/unicore32/Makefile Normal file
View File

@ -0,0 +1,95 @@
#
# arch/unicore32/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# 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) 2002~2010 by Guan Xue-tao
#
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, unicore32-linux-)
endif
endif
LDFLAGS_vmlinux := -p --no-undefined -X
OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S
# Never generate .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# Never use hard float in kernel
KBUILD_CFLAGS += -msoft-float
ifeq ($(CONFIG_FRAME_POINTER),y)
KBUILD_CFLAGS += -mno-sched-prolog
endif
CHECKFLAGS += -D__unicore32__
head-y := arch/unicore32/kernel/head.o
head-y += arch/unicore32/kernel/init_task.o
core-y += arch/unicore32/kernel/
core-y += arch/unicore32/mm/
libs-y += arch/unicore32/lib/
ASM_GENERATED_DIR := $(srctree)/arch/unicore32/include/generated
LINUXINCLUDE += -I$(ASM_GENERATED_DIR)
ASM_GENERIC_HEADERS := atomic.h auxvec.h
ASM_GENERIC_HEADERS += bitsperlong.h bug.h bugs.h
ASM_GENERIC_HEADERS += cputime.h current.h
ASM_GENERIC_HEADERS += device.h div64.h
ASM_GENERIC_HEADERS += emergency-restart.h errno.h
ASM_GENERIC_HEADERS += fb.h fcntl.h ftrace.h
ASM_GENERIC_HEADERS += hardirq.h hw_irq.h
ASM_GENERIC_HEADERS += ioctl.h ioctls.h ipcbuf.h irq_regs.h
ASM_GENERIC_HEADERS += kdebug.h kmap_types.h
ASM_GENERIC_HEADERS += local.h
ASM_GENERIC_HEADERS += mman.h module.h msgbuf.h
ASM_GENERIC_HEADERS += param.h parport.h percpu.h poll.h posix_types.h
ASM_GENERIC_HEADERS += resource.h
ASM_GENERIC_HEADERS += scatterlist.h sections.h segment.h sembuf.h serial.h
ASM_GENERIC_HEADERS += setup.h shmbuf.h shmparam.h
ASM_GENERIC_HEADERS += siginfo.h signal.h sizes.h
ASM_GENERIC_HEADERS += socket.h sockios.h stat.h statfs.h swab.h syscalls.h
ASM_GENERIC_HEADERS += termbits.h termios.h topology.h types.h
ASM_GENERIC_HEADERS += ucontext.h unaligned.h user.h
ASM_GENERIC_HEADERS += vga.h
ASM_GENERIC_HEADERS += xor.h
archprepare:
ifneq ($(ASM_GENERATED_DIR), $(wildcard $(ASM_GENERATED_DIR)))
$(Q)mkdir -p $(ASM_GENERATED_DIR)/asm
$(Q)$(foreach a, $(ASM_GENERIC_HEADERS), \
echo '#include <asm-generic/$a>' \
> $(ASM_GENERATED_DIR)/asm/$a; )
endif
boot := arch/unicore32/boot
# Default target when executing plain make
KBUILD_IMAGE := zImage
all: $(KBUILD_IMAGE)
zImage Image uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
MRPROPER_DIRS += $(ASM_GENERATED_DIR)
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
define archhelp
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo ' uImage - U-Boot wrapped zImage'
endef

View File

@ -0,0 +1,47 @@
#
# arch/unicore32/boot/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# 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~2010 GUAN Xue-tao
#
MKIMAGE := $(srctree)/scripts/mkuboot.sh
targets := Image zImage uImage
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A unicore -O linux -T kernel \
-C none -a $(LOADADDR) -e $(STARTADDR) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/uImage: LOADADDR=0x0
$(obj)/uImage: STARTADDR=$(LOADADDR)
$(obj)/uImage: $(obj)/zImage FORCE
$(call if_changed,uimage)
@echo ' Image $@ is ready'
PHONY += initrd FORCE
initrd:
@test "$(INITRD)" != "" || \
(echo You must specify INITRD; exit -1)
subdir- := compressed

View File

@ -0,0 +1,68 @@
#
# linux/arch/unicore32/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
#
# 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~2010 GUAN Xue-tao
#
EXTRA_CFLAGS := -fpic -fno-builtin
EXTRA_AFLAGS := -Wa,-march=all
OBJS := misc.o
# font.c and font.o
CFLAGS_font.o := -Dstatic=
$(obj)/font.c: $(srctree)/drivers/video/console/font_8x8.c
$(call cmd,shipped)
# piggy.S and piggy.o
suffix_$(CONFIG_KERNEL_GZIP) := gzip
suffix_$(CONFIG_KERNEL_BZIP2) := bz2
suffix_$(CONFIG_KERNEL_LZO) := lzo
suffix_$(CONFIG_KERNEL_LZMA) := lzma
$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
$(call if_changed,$(suffix_y))
SEDFLAGS_piggy = s/DECOMP_SUFFIX/$(suffix_y)/
$(obj)/piggy.S: $(obj)/piggy.S.in
@sed "$(SEDFLAGS_piggy)" < $< > $@
$(obj)/piggy.o: $(obj)/piggy.$(suffix_y) $(obj)/piggy.S FORCE
targets := vmlinux vmlinux.lds font.o font.c head.o misc.o \
piggy.$(suffix_y) piggy.o piggy.S \
# Make sure files are removed during clean
extra-y += piggy.gzip piggy.bz2 piggy.lzo piggy.lzma
# ?
LDFLAGS_vmlinux += -p
# Report unresolved symbol references
LDFLAGS_vmlinux += --no-undefined
# Delete all temporary local symbols
LDFLAGS_vmlinux += -X
# Next argument is a linker script
LDFLAGS_vmlinux += -T
# For uidivmod
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head.o $(obj)/piggy.o \
$(obj)/misc.o FORCE
$(call if_changed,ld)
@:
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
ZTEXTADDR := 0
ZBSSADDR := ALIGN(4)
SEDFLAGS_lds = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/unicore32/boot/Makefile $(KCONFIG_CONFIG)
@sed "$(SEDFLAGS_lds)" < $< > $@

View File

@ -0,0 +1,204 @@
/*
* linux/arch/unicore32/boot/compressed/head.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/linkage.h>
#include <mach/memory.h>
#define csub cmpsub
#define cand cmpand
#define nop8 nop; nop; nop; nop; nop; nop; nop; nop
.section ".start", #alloc, #execinstr
.text
start:
.type start,#function
/* Initialize ASR, PRIV mode and INTR off */
mov r0, #0xD3
mov.a asr, r0
adr r0, LC0
ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+
ldw sp, [r0+], #28
sub.a r0, r0, r1 @ calculate the delta offset
/*
* if delta is zero, we are running at the address
* we were linked at.
*/
beq not_relocated
/*
* We're running at a different address. We need to fix
* up various pointers:
* r5 - zImage base address (_start)
* r7 - GOT start
* r8 - GOT end
*/
add r5, r5, r0
add r7, r7, r0
add r8, r8, r0
/*
* we need to fix up pointers into the BSS region.
* r2 - BSS start
* r3 - BSS end
* sp - stack pointer
*/
add r2, r2, r0
add r3, r3, r0
add sp, sp, r0
/*
* Relocate all entries in the GOT table.
* This fixes up the C references.
* r7 - GOT start
* r8 - GOT end
*/
1001: ldw r1, [r7+], #0
add r1, r1, r0
stw.w r1, [r7]+, #4
csub.a r7, r8
bub 1001b
not_relocated:
/*
* Clear BSS region.
* r2 - BSS start
* r3 - BSS end
*/
mov r0, #0
1002: stw.w r0, [r2]+, #4
csub.a r2, r3
bub 1002b
/*
* Turn on the cache.
*/
mov r0, #0
movc p0.c5, r0, #28 @ cache invalidate all
nop8
movc p0.c6, r0, #6 @ tlb invalidate all
nop8
mov r0, #0x1c @ en icache and wb dcache
movc p0.c1, r0, #0
nop8
/*
* Set up some pointers, for starting decompressing.
*/
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
/*
* Check to see if we will overwrite ourselves.
* r4 = final kernel address
* r5 = start of this image
* r6 = size of decompressed image
* r2 = end of malloc space (and therefore this image)
* We basically want:
* r4 >= r2 -> OK
* r4 + image length <= r5 -> OK
*/
ldw r4, =KERNEL_IMAGE_START
csub.a r4, r2
bea wont_overwrite
add r0, r4, r6
csub.a r0, r5
beb wont_overwrite
/*
* If overwrite, just print error message
*/
b __error_overwrite
/*
* We're not in danger of overwriting ourselves.
* Do this the simple way.
*/
wont_overwrite:
/*
* decompress_kernel:
* r0: output_start
* r1: free_mem_ptr_p
* r2: free_mem_ptr_end_p
*/
mov r0, r4
b.l decompress_kernel @ C functions
/*
* Clean and flush the cache to maintain consistency.
*/
mov r0, #0
movc p0.c5, r0, #14 @ flush dcache
nop8
movc p0.c5, r0, #20 @ icache invalidate all
nop8
/*
* Turn off the Cache and MMU.
*/
mov r0, #0 @ disable i/d cache and MMU
movc p0.c1, r0, #0
nop8
mov r0, #0 @ must be zero
ldw r4, =KERNEL_IMAGE_START
mov pc, r4 @ call kernel
.align 2
.type LC0, #object
LC0: .word LC0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word _start @ r5
.word _image_size @ r6
.word _got_start @ r7
.word _got_end @ r8
.word decompress_stack_end @ sp
.size LC0, . - LC0
print_string:
#ifdef CONFIG_DEBUG_OCD
2001: ldb.w r1, [r0]+, #1
csub.a r1, #0
bne 2002f
mov pc, lr
2002:
movc r2, p1.c0, #0
cand.a r2, #2
bne 2002b
movc p1.c1, r1, #1
csub.a r1, #'\n'
cmoveq r1, #'\r'
beq 2002b
b 2001b
#else
mov pc, lr
#endif
__error_overwrite:
adr r0, str_error
b.l print_string
2001: nop8
b 2001b
str_error: .asciz "\nError: Kernel address OVERWRITE\n"
.align
.ltorg
.align 4
.section ".stack", "aw", %nobits
decompress_stack: .space 4096
decompress_stack_end:

View File

@ -0,0 +1,126 @@
/*
* linux/arch/unicore32/boot/compressed/misc.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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 <asm/unaligned.h>
#include <mach/uncompress.h>
/*
* gzip delarations
*/
unsigned char *output_data;
unsigned long output_ptr;
unsigned int free_mem_ptr;
unsigned int free_mem_end_ptr;
#define STATIC static
#define STATIC_RW_DATA /* non-static please */
/*
* arch-dependent implementations
*/
#ifndef ARCH_HAVE_DECOMP_ERROR
#define arch_decomp_error(x)
#endif
#ifndef ARCH_HAVE_DECOMP_SETUP
#define arch_decomp_setup()
#endif
#ifndef ARCH_HAVE_DECOMP_PUTS
#define arch_decomp_puts(p)
#endif
void *memcpy(void *dest, const void *src, size_t n)
{
int i = 0;
unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src;
for (i = n >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
*d++ = *s++;
return dest;
}
void error(char *x)
{
arch_decomp_puts("\n\n");
arch_decomp_puts(x);
arch_decomp_puts("\n\n -- System halted");
arch_decomp_error(x);
for (;;)
; /* Halt */
}
/* Heap size should be adjusted for different decompress method */
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_BZIP2
#include "../../../../lib/decompress_bunzip2.c"
#endif
#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
unsigned long decompress_kernel(unsigned long output_start,
unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p)
{
unsigned char *tmp;
output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p;
arch_decomp_setup();
tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
output_ptr = get_unaligned_le32(tmp);
arch_decomp_puts("Uncompressing Linux...");
decompress(input_data, input_data_end - input_data, NULL, NULL,
output_data, NULL, error);
arch_decomp_puts(" done, booting the kernel.\n");
return output_ptr;
}

View File

@ -0,0 +1,6 @@
.section .piggydata,#alloc
.globl input_data
input_data:
.incbin "arch/unicore32/boot/compressed/piggy.DECOMP_SUFFIX"
.globl input_data_end
input_data_end:

View File

@ -0,0 +1,61 @@
/*
* linux/arch/unicore/boot/compressed/vmlinux.lds.in
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
OUTPUT_ARCH(unicore32)
ENTRY(_start)
SECTIONS
{
/DISCARD/ : {
/*
* Discard any r/w data - this produces a link error if we have any,
* which is required for PIC decompression. Local data generates
* GOTOFF relocations, which prevents it being relocated independently
* of the text/got segments.
*/
*(.data)
}
. = TEXT_START;
_text = .;
.text : {
_start = .;
*(.start)
*(.text)
*(.text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata)
*(.rodata.*)
*(.piggydata)
. = ALIGN(4);
}
_etext = .;
/* Assume size of decompressed image is 4x the compressed image */
_image_size = (_etext - _text) * 4;
_got_start = .;
.got : { *(.got) }
_got_end = .;
.got.plt : { *(.got.plt) }
_edata = .;
. = BSS_START;
__bss_start = .;
.bss : { *(.bss) }
_end = .;
.stack : { *(.stack) }
.comment 0 : { *(.comment) }
}

View File

@ -0,0 +1,215 @@
### General setup
CONFIG_EXPERIMENTAL=y
CONFIG_LOCALVERSION="-debug"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_HOTPLUG=y
# Initial RAM filesystem and RAM disk (initramfs/initrd) support
#CONFIG_BLK_DEV_INITRD=y
#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
### Enable loadable module support
CONFIG_MODULES=n
CONFIG_MODULE_UNLOAD=y
### System Type
CONFIG_ARCH_PUV3=y
# Board Selection
CONFIG_PUV3_NB0916=y
# Processor Features
CONFIG_CPU_DCACHE_LINE_DISABLE=y
CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
### Bus support
CONFIG_PCI=y
CONFIG_PCI_LEGACY=n
### Boot options
# for debug, adding: earlyprintk=ocd,keep initcall_debug
# others support: test_suspend=mem root=/dev/sda
# hibernate support: resume=/dev/sda3
CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
# TODO: mem=512M video=unifb:1024x600-16@75
# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
# ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
CONFIG_CMDLINE_FORCE=y
### Power management options
CONFIG_PM=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION="/dev/sda3"
CONFIG_CPU_FREQ=n
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
### Networking support
CONFIG_NET=y
# Networking options
CONFIG_PACKET=m
CONFIG_UNIX=m
# TCP/IP networking
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IPV6=n
# Wireless
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_MAC80211=m
### PKUnity SoC Features
CONFIG_USB_WLAN_HED_AQ3=n
CONFIG_USB_CMMB_INNOFIDEI=n
CONFIG_I2C_BATTERY_BQ27200=n
CONFIG_I2C_EEPROM_AT24=n
CONFIG_LCD_BACKLIGHT=n
CONFIG_PUV3_RTC=y
CONFIG_PUV3_UMAL=y
CONFIG_PUV3_MUSB=n
CONFIG_PUV3_AC97=n
CONFIG_PUV3_NAND=n
CONFIG_PUV3_MMC=n
CONFIG_PUV3_UART=n
### Device Drivers
# Memory Technology Device (MTD) support
CONFIG_MTD=m
CONFIG_MTD_UBI=m
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=m
CONFIG_MTD_BLKDEVS=m
# RAM/ROM/Flash chip drivers
CONFIG_MTD_CFI=m
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_CFI_AMDSTD=m
# Mapping drivers for chip access
CONFIG_MTD_PHYSMAP=m
# Block devices
CONFIG_BLK_DEV_LOOP=m
# SCSI device support
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
# Serial ATA (prod) and Parallel ATA (experimental) drivers
CONFIG_ATA=y
CONFIG_SATA_VIA=y
# Network device support
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NETDEV_1000=y
# Wireless LAN
CONFIG_WLAN_80211=n
CONFIG_RT2X00=n
CONFIG_RT73USB=n
# Input device support
CONFIG_INPUT_EVDEV=m
# Keyboards
CONFIG_KEYBOARD_GPIO=m
# I2C support
CONFIG_I2C=y
CONFIG_I2C_PUV3=y
# Hardware Monitoring support
#CONFIG_SENSORS_LM75=m
# Generic Thermal sysfs driver
#CONFIG_THERMAL=m
#CONFIG_THERMAL_HWMON=y
# Multimedia support
CONFIG_MEDIA_SUPPORT=n
CONFIG_VIDEO_DEV=n
CONFIG_USB_VIDEO_CLASS=n
# Graphics support
CONFIG_FB=y
CONFIG_FB_PUV3_UNIGFX=y
# Console display driver support
CONFIG_VGA_CONSOLE=n
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# Bootup logo
CONFIG_LOGO=n
# Sound card support
CONFIG_SOUND=m
# Advanced Linux Sound Architecture
CONFIG_SND=m
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
# USB support
CONFIG_USB_ARCH_HAS_HCD=n
CONFIG_USB=n
CONFIG_USB_DEVICEFS=n
CONFIG_USB_PRINTER=n
CONFIG_USB_STORAGE=n
# Inventra Highspeed Dual Role Controller
CONFIG_USB_MUSB_HDRC=n
# LED Support
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
# LED Triggers
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# Real Time Clock
CONFIG_RTC_LIB=m
CONFIG_RTC_CLASS=m
### File systems
CONFIG_EXT2_FS=m
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_FUSE_FS=m
# CD-ROM/DVD Filesystems
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_UDF_FS=m
# DOS/FAT/NT Filesystems
CONFIG_VFAT_FS=m
# Pseudo filesystems
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# Miscellaneous filesystems
CONFIG_MISC_FILESYSTEMS=y
CONFIG_JFFS2_FS=m
CONFIG_UBIFS_FS=m
# Network File Systems
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
# Partition Types
CONFIG_PARTITION_ADVANCED=y
CONFIG_MSDOS_PARTITION=y
# Native language support
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_UTF8=m
### Kernel hacking
CONFIG_FRAME_WARN=8096
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_PROVE_LOCKING=n
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_LL=y

View File

@ -0,0 +1,2 @@
include include/asm-generic/Kbuild.asm

View File

@ -0,0 +1,131 @@
/*
* linux/arch/unicore32/include/asm/assembler.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Do not include any C declarations in this file - it is included by
* assembler source.
*/
#ifndef __ASSEMBLY__
#error "Only include this from assembly code"
#endif
#include <asm/ptrace.h>
/*
* Little Endian independent macros for shifting bytes within registers.
*/
#define pull >>
#define push <<
#define get_byte_0 << #0
#define get_byte_1 >> #8
#define get_byte_2 >> #16
#define get_byte_3 >> #24
#define put_byte_0 << #0
#define put_byte_1 << #8
#define put_byte_2 << #16
#define put_byte_3 << #24
#define cadd cmpadd
#define cand cmpand
#define csub cmpsub
#define cxor cmpxor
/*
* Enable and disable interrupts
*/
.macro disable_irq, temp
mov \temp, asr
andn \temp, \temp, #0xFF
or \temp, \temp, #PSR_I_BIT | PRIV_MODE
mov.a asr, \temp
.endm
.macro enable_irq, temp
mov \temp, asr
andn \temp, \temp, #0xFF
or \temp, \temp, #PRIV_MODE
mov.a asr, \temp
.endm
#define USER(x...) \
9999: x; \
.pushsection __ex_table, "a"; \
.align 3; \
.long 9999b, 9001f; \
.popsection
.macro notcond, cond, nexti = .+8
.ifc \cond, eq
bne \nexti
.else; .ifc \cond, ne
beq \nexti
.else; .ifc \cond, ea
bub \nexti
.else; .ifc \cond, ub
bea \nexti
.else; .ifc \cond, fs
bns \nexti
.else; .ifc \cond, ns
bfs \nexti
.else; .ifc \cond, fv
bnv \nexti
.else; .ifc \cond, nv
bfv \nexti
.else; .ifc \cond, ua
beb \nexti
.else; .ifc \cond, eb
bua \nexti
.else; .ifc \cond, eg
bsl \nexti
.else; .ifc \cond, sl
beg \nexti
.else; .ifc \cond, sg
bel \nexti
.else; .ifc \cond, el
bsg \nexti
.else; .ifnc \cond, al
.error "Unknown cond in notcond macro argument"
.endif; .endif; .endif; .endif; .endif; .endif; .endif
.endif; .endif; .endif; .endif; .endif; .endif; .endif
.endif
.endm
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
.rept \rept
notcond \cond, .+8
9999 :
.if \inc == 1
\instr\()b.u \reg, [\ptr], #\inc
.elseif \inc == 4
\instr\()w.u \reg, [\ptr], #\inc
.else
.error "Unsupported inc macro argument"
.endif
.pushsection __ex_table, "a"
.align 3
.long 9999b, \abort
.popsection
.endr
.endm
.macro strusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
usracc st, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
.macro ldrusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
usracc ld, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
.macro nop8
.rept 8
nop
.endr
.endm

View File

@ -0,0 +1,47 @@
/*
* linux/arch/unicore32/include/asm/bitops.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_BITOPS_H__
#define __UNICORE_BITOPS_H__
#define find_next_bit __uc32_find_next_bit
#define find_next_zero_bit __uc32_find_next_zero_bit
#define find_first_bit __uc32_find_first_bit
#define find_first_zero_bit __uc32_find_first_zero_bit
#define _ASM_GENERIC_BITOPS_FLS_H_
#define _ASM_GENERIC_BITOPS___FLS_H_
#define _ASM_GENERIC_BITOPS_FFS_H_
#define _ASM_GENERIC_BITOPS___FFS_H_
/*
* On UNICORE, those functions can be implemented around
* the cntlz instruction for much better code efficiency.
*/
static inline int fls(int x)
{
int ret;
asm("cntlz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
ret = 32 - ret;
return ret;
}
#define __fls(x) (fls(x) - 1)
#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
#define __ffs(x) (ffs(x) - 1)
#include <asm-generic/bitops.h>
#endif /* __UNICORE_BITOPS_H__ */

View File

@ -0,0 +1,24 @@
/*
* linux/arch/unicore32/include/asm/byteorder.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* UniCore ONLY support Little Endian mode, the data bus is connected such
* that byte accesses appear as:
* 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
* and word accesses (data or instruction) appear as:
* d0...d31
*/
#ifndef __UNICORE_BYTEORDER_H__
#define __UNICORE_BYTEORDER_H__
#include <linux/byteorder/little_endian.h>
#endif

View File

@ -0,0 +1,27 @@
/*
* linux/arch/unicore32/include/asm/cache.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_CACHE_H__
#define __UNICORE_CACHE_H__
#define L1_CACHE_SHIFT (5)
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
* sure that all such allocations are cache aligned. Otherwise,
* unrelated code may cause parts of the buffer to be read into the
* cache before the transfer is done, causing old data to be seen by
* the CPU.
*/
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
#endif

View File

@ -0,0 +1,211 @@
/*
* linux/arch/unicore32/include/asm/cacheflush.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_CACHEFLUSH_H__
#define __UNICORE_CACHEFLUSH_H__
#include <linux/mm.h>
#include <asm/shmparam.h>
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
/*
* This flag is used to indicate that the page pointed to by a pte is clean
* and does not require cleaning before returning it to the user.
*/
#define PG_dcache_clean PG_arch_1
/*
* MM Cache Management
* ===================
*
* The arch/unicore32/mm/cache.S files implement these methods.
*
* Start addresses are inclusive and end addresses are exclusive;
* start addresses should be rounded down, end addresses up.
*
* See Documentation/cachetlb.txt for more information.
* Please note that the implementation of these, and the required
* effects are cache-type (VIVT/VIPT/PIPT) specific.
*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
* Currently only needed for cache-v6.S and cache-v7.S, see
* __flush_icache_all for the generic implementation.
*
* flush_kern_all()
*
* Unconditionally clean and invalidate the entire cache.
*
* flush_user_all()
*
* Clean and invalidate all user space cache entries
* before a change of page tables.
*
* flush_user_range(start, end, flags)
*
* Clean and invalidate a range of cache entries in the
* specified address space before a change of page tables.
* - start - user start address (inclusive, page aligned)
* - end - user end address (exclusive, page aligned)
* - flags - vma->vm_flags field
*
* coherent_kern_range(start, end)
*
* Ensure coherency between the Icache and the Dcache in the
* region described by start, end. If you have non-snooping
* Harvard caches, you need to implement this function.
* - start - virtual start address
* - end - virtual end address
*
* coherent_user_range(start, end)
*
* Ensure coherency between the Icache and the Dcache in the
* region described by start, end. If you have non-snooping
* Harvard caches, you need to implement this function.
* - start - virtual start address
* - end - virtual end address
*
* flush_kern_dcache_area(kaddr, size)
*
* Ensure that the data held in page is written back.
* - kaddr - page address
* - size - region size
*
* DMA Cache Coherency
* ===================
*
* dma_flush_range(start, end)
*
* Clean and invalidate the specified virtual address range.
* - start - virtual start address
* - end - virtual end address
*/
extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
extern void __cpuc_flush_user_all(void);
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
extern void __cpuc_flush_dcache_area(void *, size_t);
extern void __cpuc_flush_kern_dcache_area(void *addr, size_t size);
/*
* These are private to the dma-mapping API. Do not use directly.
* Their sole purpose is to ensure that data held in the cache
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
extern void __cpuc_dma_clean_range(unsigned long, unsigned long);
extern void __cpuc_dma_flush_range(unsigned long, unsigned long);
/*
* Copy user data from/to a page which is mapped into a different
* processes address space. Really, we want to allow our "user
* space" model to handle this.
*/
extern void copy_to_user_page(struct vm_area_struct *, struct page *,
unsigned long, void *, const void *, unsigned long);
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy(dst, src, len); \
} while (0)
/*
* Convert calls to our calling convention.
*/
/* Invalidate I-cache */
static inline void __flush_icache_all(void)
{
asm("movc p0.c5, %0, #20;\n"
"nop; nop; nop; nop; nop; nop; nop; nop\n"
:
: "r" (0));
}
#define flush_cache_all() __cpuc_flush_kern_all()
extern void flush_cache_mm(struct mm_struct *mm);
extern void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void flush_cache_page(struct vm_area_struct *vma,
unsigned long user_addr, unsigned long pfn);
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
/*
* flush_cache_user_range is used when we want to ensure that the
* Harvard caches are synchronised for the user space address range.
* This is used for the UniCore private sys_cacheflush system call.
*/
#define flush_cache_user_range(vma, start, end) \
__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
/*
* Perform necessary cache operations to ensure that data previously
* stored within this range of addresses can be executed by the CPU.
*/
#define flush_icache_range(s, e) __cpuc_coherent_kern_range(s, e)
/*
* Perform necessary cache operations to ensure that the TLB will
* see data written in the specified area.
*/
#define clean_dcache_area(start, size) cpu_dcache_clean_area(start, size)
/*
* flush_dcache_page is used when the kernel has written to the page
* cache page at virtual address page->virtual.
*
* If this page isn't mapped (ie, page_mapping == NULL), or it might
* have userspace mappings, then we _must_ always clean + invalidate
* the dcache entries associated with the kernel mapping.
*
* Otherwise we can defer the operation, and clean the cache when we are
* about to change to user space. This is the same method as used on SPARC64.
* See update_mmu_cache for the user space part.
*/
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *);
#define flush_dcache_mmap_lock(mapping) \
spin_lock_irq(&(mapping)->tree_lock)
#define flush_dcache_mmap_unlock(mapping) \
spin_unlock_irq(&(mapping)->tree_lock)
#define flush_icache_user_range(vma, page, addr, len) \
flush_dcache_page(page)
/*
* We don't appear to need to do anything here. In fact, if we did, we'd
* duplicate cache flushing elsewhere performed by flush_dcache_page().
*/
#define flush_icache_page(vma, page) do { } while (0)
/*
* flush_cache_vmap() is used when creating mappings (eg, via vmap,
* vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
* caches, since the direct-mappings of these pages may contain cached
* data, we need to do a full cache flush to ensure that writebacks
* don't corrupt data placed into these pages via the new mappings.
*/
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
{
}
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
{
}
#endif

View File

@ -0,0 +1,41 @@
/*
* linux/arch/unicore32/include/asm/checksum.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* IP checksum routines
*/
#ifndef __UNICORE_CHECKSUM_H__
#define __UNICORE_CHECKSUM_H__
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__(
"add.a %0, %1, %2\n"
"addc.a %0, %0, %3\n"
"addc.a %0, %0, %4 << #8\n"
"addc.a %0, %0, %5\n"
"addc %0, %0, #0\n"
: "=&r"(sum)
: "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
: "cc");
return sum;
}
#define csum_tcpudp_nofold csum_tcpudp_nofold
#include <asm-generic/checksum.h>
#endif

View File

@ -0,0 +1,45 @@
/*
* linux/arch/unicore32/include/asm/cpu-single.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_CPU_SINGLE_H__
#define __UNICORE_CPU_SINGLE_H__
#include <asm/page.h>
#include <asm/memory.h>
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define cpu_switch_mm(pgd, mm) cpu_do_switch_mm(virt_to_phys(pgd), mm)
#define cpu_get_pgd() \
({ \
unsigned long pg; \
__asm__("movc %0, p0.c2, #0" \
: "=r" (pg) : : "cc"); \
pg &= ~0x0fff; \
(pgd_t *)phys_to_virt(pg); \
})
struct mm_struct;
/* declare all the functions as extern */
extern void cpu_proc_fin(void);
extern int cpu_do_idle(void);
extern void cpu_dcache_clean_area(void *, int);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pte(pte_t *ptep, pte_t pte);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __UNICORE_CPU_SINGLE_H__ */

View File

@ -0,0 +1,33 @@
/*
* linux/arch/unicore32/include/asm/cputype.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_CPUTYPE_H__
#define __UNICORE_CPUTYPE_H__
#include <linux/stringify.h>
#define CPUID_CPUID 0
#define CPUID_CACHETYPE 1
#define read_cpuid(reg) \
({ \
unsigned int __val; \
asm("movc %0, p0.c0, #" __stringify(reg) \
: "=r" (__val) \
: \
: "cc"); \
__val; \
})
#define uc32_cpuid read_cpuid(CPUID_CPUID)
#define uc32_cachetype read_cpuid(CPUID_CACHETYPE)
#endif

View File

@ -0,0 +1,52 @@
/*
* linux/arch/unicore32/include/asm/delay.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Delay routines, using a pre-computed "loops_per_second" value.
*/
#ifndef __UNICORE_DELAY_H__
#define __UNICORE_DELAY_H__
#include <asm/param.h> /* HZ */
extern void __delay(int loops);
/*
* This function intentionally does not exist; if you see references to
* it, it means that you're calling udelay() with an out of range value.
*
* With currently imposed limits, this means that we support a max delay
* of 2000us. Further limits: HZ<=1000 and bogomips<=3355
*/
extern void __bad_udelay(void);
/*
* division by multiplication: you don't have to worry about
* loss of precision.
*
* Use only for very small delays ( < 1 msec). Should probably use a
* lookup table, really, as the multiplications take much too long with
* short delays. This is a "reasonable" implementation, though (and the
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
extern void __udelay(unsigned long usecs);
extern void __const_udelay(unsigned long);
#define MAX_UDELAY_MS 2
#define udelay(n) \
(__builtin_constant_p(n) ? \
((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
__const_udelay((n) * ((2199023U*HZ)>>11))) : \
__udelay(n))
#endif /* __UNICORE_DELAY_H__ */

View File

@ -0,0 +1,124 @@
/*
* linux/arch/unicore32/include/asm/dma-mapping.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_DMA_MAPPING_H__
#define __UNICORE_DMA_MAPPING_H__
#ifdef __KERNEL__
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
#include <linux/swiotlb.h>
#include <asm-generic/dma-coherent.h>
#include <asm/memory.h>
#include <asm/cacheflush.h>
extern struct dma_map_ops swiotlb_dma_map_ops;
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
return &swiotlb_dma_map_ops;
}
static inline int dma_supported(struct device *dev, u64 mask)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
if (unlikely(dma_ops == NULL))
return 0;
return dma_ops->dma_supported(dev, mask);
}
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
if (dma_ops->mapping_error)
return dma_ops->mapping_error(dev, dma_addr);
return 0;
}
#include <asm-generic/dma-mapping-common.h>
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (dev && dev->dma_mask)
return addr + size - 1 <= *dev->dma_mask;
return 1;
}
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return paddr;
}
static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
{
return daddr;
}
static inline void dma_mark_clean(void *addr, size_t size) {}
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
*dev->dma_mask = dma_mask;
return 0;
}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
}
static inline void dma_free_coherent(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_handle)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
}
#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)
static inline void dma_cache_sync(struct device *dev, void *vaddr,
size_t size, enum dma_data_direction direction)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
switch (direction) {
case DMA_NONE:
BUG();
case DMA_FROM_DEVICE:
case DMA_BIDIRECTIONAL: /* writeback and invalidate */
__cpuc_dma_flush_range(start, end);
break;
case DMA_TO_DEVICE: /* writeback only */
__cpuc_dma_clean_range(start, end);
break;
}
}
#endif /* __KERNEL__ */
#endif

View File

@ -0,0 +1,23 @@
/*
* linux/arch/unicore32/include/asm/dma.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_DMA_H__
#define __UNICORE_DMA_H__
#include <asm/memory.h>
#include <asm-generic/dma.h>
#ifdef CONFIG_PCI
extern int isa_dma_bridge_buggy;
#endif
#endif /* __UNICORE_DMA_H__ */

View File

@ -0,0 +1,94 @@
/*
* linux/arch/unicore32/include/asm/elf.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_ELF_H__
#define __UNICORE_ELF_H__
#include <asm/hwcap.h>
/*
* ELF register definitions..
*/
#include <asm/ptrace.h>
typedef unsigned long elf_greg_t;
typedef unsigned long elf_freg_t[3];
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct fp_state elf_fpregset_t;
#define EM_UNICORE 110
#define R_UNICORE_NONE 0
#define R_UNICORE_PC24 1
#define R_UNICORE_ABS32 2
#define R_UNICORE_CALL 28
#define R_UNICORE_JUMP24 29
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_UNICORE
/*
* This yields a string that ld.so will use to load implementation
* specific libraries for optimization. This is more specific in
* intent than poking at uname or /proc/cpuinfo.
*
*/
#define ELF_PLATFORM_SIZE 8
#define ELF_PLATFORM (elf_platform)
extern char elf_platform[];
struct elf32_hdr;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
extern int elf_check_arch(const struct elf32_hdr *);
#define elf_check_arch elf_check_arch
struct task_struct;
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
#define ELF_CORE_COPY_TASK_REGS dump_task_regs
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. */
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
/* When the program starts, a1 contains a pointer to a function to be
registered with atexit, as per the SVR4 ABI. A value of 0 means we
have no such handler. */
#define ELF_PLAT_INIT(_r, load_addr) {(_r)->UCreg_00 = 0; }
extern void elf_set_personality(const struct elf32_hdr *);
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
struct mm_struct;
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
extern int vectors_user_mapping(void);
#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
#endif

View File

@ -0,0 +1,26 @@
/*
* linux/arch/unicore32/include/asm/fpstate.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_FPSTATE_H__
#define __UNICORE_FPSTATE_H__
#ifndef __ASSEMBLY__
#define FP_REGS_NUMBER 33
struct fp_state {
unsigned int regs[FP_REGS_NUMBER];
} __attribute__((aligned(8)));
#endif
#endif

View File

@ -0,0 +1,53 @@
/*
* linux/arch/unicore32/include/asm/fpu-ucf64.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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.
*/
#define FPSCR s31
/* FPSCR bits */
#define FPSCR_DEFAULT_NAN (1<<25)
#define FPSCR_CMPINSTR_BIT (1<<31)
#define FPSCR_CON (1<<29)
#define FPSCR_TRAP (1<<27)
/* RND mode */
#define FPSCR_ROUND_NEAREST (0<<0)
#define FPSCR_ROUND_PLUSINF (2<<0)
#define FPSCR_ROUND_MINUSINF (3<<0)
#define FPSCR_ROUND_TOZERO (1<<0)
#define FPSCR_RMODE_BIT (0)
#define FPSCR_RMODE_MASK (7 << FPSCR_RMODE_BIT)
/* trap enable */
#define FPSCR_IOE (1<<16)
#define FPSCR_OFE (1<<14)
#define FPSCR_UFE (1<<13)
#define FPSCR_IXE (1<<12)
#define FPSCR_HIE (1<<11)
#define FPSCR_NDE (1<<10) /* non denomal */
/* flags */
#define FPSCR_IDC (1<<24)
#define FPSCR_HIC (1<<23)
#define FPSCR_IXC (1<<22)
#define FPSCR_OFC (1<<21)
#define FPSCR_UFC (1<<20)
#define FPSCR_IOC (1<<19)
/* stick bits */
#define FPSCR_IOS (1<<9)
#define FPSCR_OFS (1<<7)
#define FPSCR_UFS (1<<6)
#define FPSCR_IXS (1<<5)
#define FPSCR_HIS (1<<4)
#define FPSCR_NDS (1<<3) /*non denomal */

View File

@ -0,0 +1,143 @@
/*
* linux/arch/unicore32/include/asm/futex.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_FUTEX_H__
#define __UNICORE_FUTEX_H__
#ifdef __KERNEL__
#include <linux/futex.h>
#include <linux/preempt.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile__( \
"1: ldw.u %1, [%2]\n" \
" " insn "\n" \
"2: stw.u %0, [%2]\n" \
" mov %0, #0\n" \
"3:\n" \
" .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4f, 2b, 4f\n" \
" .popsection\n" \
" .pushsection .fixup,\"ax\"\n" \
"4: mov %0, %4\n" \
" b 3b\n" \
" .popsection" \
: "=&r" (ret), "=&r" (oldval) \
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
: "cc", "memory")
static inline int
futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
pagefault_disable(); /* implies preempt_disable() */
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %0, %1, %3", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("and %0, %1, %3",
ret, oldval, uaddr, ~oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable(); /* subsumes preempt_enable() */
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ:
ret = (oldval == cmparg);
break;
case FUTEX_OP_CMP_NE:
ret = (oldval != cmparg);
break;
case FUTEX_OP_CMP_LT:
ret = (oldval < cmparg);
break;
case FUTEX_OP_CMP_GE:
ret = (oldval >= cmparg);
break;
case FUTEX_OP_CMP_LE:
ret = (oldval <= cmparg);
break;
case FUTEX_OP_CMP_GT:
ret = (oldval > cmparg);
break;
default:
ret = -ENOSYS;
}
}
return ret;
}
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
int val;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
pagefault_disable(); /* implies preempt_disable() */
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
"1: ldw.u %0, [%3]\n"
" cmpxor.a %0, %1\n"
" bne 3f\n"
"2: stw.u %2, [%3]\n"
"3:\n"
" .pushsection __ex_table,\"a\"\n"
" .align 3\n"
" .long 1b, 4f, 2b, 4f\n"
" .popsection\n"
" .pushsection .fixup,\"ax\"\n"
"4: mov %0, %4\n"
" b 3b\n"
" .popsection"
: "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
: "cc", "memory");
pagefault_enable(); /* subsumes preempt_enable() */
return val;
}
#endif /* __KERNEL__ */
#endif /* __UNICORE_FUTEX_H__ */

View File

@ -0,0 +1,104 @@
/*
* linux/arch/unicore32/include/asm/gpio.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_GPIO_H__
#define __UNICORE_GPIO_H__
#include <linux/io.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm-generic/gpio.h>
#define GPI_OTP_INT 0
#define GPI_PCI_INTA 1
#define GPI_PCI_INTB 2
#define GPI_PCI_INTC 3
#define GPI_PCI_INTD 4
#define GPI_BAT_DET 5
#define GPI_SD_CD 6
#define GPI_SOFF_REQ 7
#define GPI_SD_WP 8
#define GPI_LCD_CASE_OFF 9
#define GPO_WIFI_EN 10
#define GPO_HDD_LED 11
#define GPO_VGA_EN 12
#define GPO_LCD_EN 13
#define GPO_LED_DATA 14
#define GPO_LED_CLK 15
#define GPO_CAM_PWR_EN 16
#define GPO_LCD_VCC_EN 17
#define GPO_SOFT_OFF 18
#define GPO_BT_EN 19
#define GPO_FAN_ON 20
#define GPO_SPKR 21
#define GPO_SET_V1 23
#define GPO_SET_V2 24
#define GPO_CPU_HEALTH 25
#define GPO_LAN_SEL 26
#ifdef CONFIG_PUV3_NB0916
#define GPI_BTN_TOUCH 14
#define GPIO_IN 0x000043ff /* 1 for input */
#define GPIO_OUT 0x0fffbc00 /* 1 for output */
#endif /* CONFIG_PUV3_NB0916 */
#ifdef CONFIG_PUV3_SMW0919
#define GPIO_IN 0x000003ff /* 1 for input */
#define GPIO_OUT 0x0ffffc00 /* 1 for output */
#endif /* CONFIG_PUV3_SMW0919 */
#ifdef CONFIG_PUV3_DB0913
#define GPIO_IN 0x000001df /* 1 for input */
#define GPIO_OUT 0x03fee800 /* 1 for output */
#endif /* CONFIG_PUV3_DB0913 */
#define GPIO_DIR (~((GPIO_IN) | 0xf0000000))
/* 0 input, 1 output */
static inline int gpio_get_value(unsigned gpio)
{
if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
return readl(GPIO_GPLR) & GPIO_GPIO(gpio);
else
return __gpio_get_value(gpio);
}
static inline void gpio_set_value(unsigned gpio, int value)
{
if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
if (value)
writel(GPIO_GPIO(gpio), GPIO_GPSR);
else
writel(GPIO_GPIO(gpio), GPIO_GPCR);
else
__gpio_set_value(gpio, value);
}
#define gpio_cansleep __gpio_cansleep
static inline unsigned gpio_to_irq(unsigned gpio)
{
if ((gpio < IRQ_GPIOHIGH) && (FIELD(1, 1, gpio) & readl(GPIO_GPIR)))
return IRQ_GPIOLOW0 + gpio;
else
return IRQ_GPIO0 + gpio;
}
static inline unsigned irq_to_gpio(unsigned irq)
{
if (irq < IRQ_GPIOHIGH)
return irq - IRQ_GPIOLOW0;
else
return irq - IRQ_GPIO0;
}
#endif /* __UNICORE_GPIO_H__ */

View File

@ -0,0 +1,32 @@
/*
* linux/arch/unicore32/include/asm/hwcap.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_HWCAP_H__
#define __UNICORE_HWCAP_H__
/*
* HWCAP flags
*/
#define HWCAP_MSP 1
#define HWCAP_UNICORE16 2
#define HWCAP_CMOV 4
#define HWCAP_UNICORE_F64 8
#define HWCAP_TLS 0x80
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
/*
* This yields a mask that user programs can use to figure out what
* instruction set this cpu supports.
*/
#define ELF_HWCAP (HWCAP_CMOV | HWCAP_UNICORE_F64)
#endif
#endif

View File

@ -0,0 +1,55 @@
/*
* linux/arch/unicore32/include/asm/io.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_IO_H__
#define __UNICORE_IO_H__
#ifdef __KERNEL__
#include <asm/byteorder.h>
#include <asm/memory.h>
#include <asm/system.h>
#define PCI_IOBASE PKUNITY_PCILIO_BASE
#include <asm-generic/io.h>
/*
* __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.
*/
extern void __iomem *__uc32_ioremap(unsigned long, size_t);
extern void __iomem *__uc32_ioremap_cached(unsigned long, size_t);
extern void __uc32_iounmap(volatile void __iomem *addr);
/*
* ioremap and friends.
*
* ioremap takes a PCI memory address, as specified in
* Documentation/IO-mapping.txt.
*
*/
#define ioremap(cookie, size) __uc32_ioremap(cookie, size)
#define ioremap_cached(cookie, size) __uc32_ioremap_cached(cookie, size)
#define iounmap(cookie) __uc32_iounmap(cookie)
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
#undef xlate_dev_mem_ptr
#define xlate_dev_mem_ptr(p) __va(p)
#define HAVE_ARCH_PIO_SIZE
#define PIO_OFFSET (unsigned int)(PCI_IOBASE)
#define PIO_MASK (unsigned int)(IO_SPACE_LIMIT)
#define PIO_RESERVED (PIO_OFFSET + PIO_MASK + 1)
#endif /* __KERNEL__ */
#endif /* __UNICORE_IO_H__ */

View File

@ -0,0 +1,105 @@
/*
* linux/arch/unicore32/include/asm/irq.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_IRQ_H__
#define __UNICORE_IRQ_H__
#include <asm-generic/irq.h>
#define IRQ_GPIOLOW0 0x00
#define IRQ_GPIOLOW1 0x01
#define IRQ_GPIOLOW2 0x02
#define IRQ_GPIOLOW3 0x03
#define IRQ_GPIOLOW4 0x04
#define IRQ_GPIOLOW5 0x05
#define IRQ_GPIOLOW6 0x06
#define IRQ_GPIOLOW7 0x07
#define IRQ_GPIOHIGH 0x08
#define IRQ_USB 0x09
#define IRQ_SDC 0x0a
#define IRQ_AC97 0x0b
#define IRQ_SATA 0x0c
#define IRQ_MME 0x0d
#define IRQ_PCI_BRIDGE 0x0e
#define IRQ_DDR 0x0f
#define IRQ_SPI 0x10
#define IRQ_UNIGFX 0x11
#define IRQ_I2C 0x11
#define IRQ_UART1 0x12
#define IRQ_UART0 0x13
#define IRQ_UMAL 0x14
#define IRQ_NAND 0x15
#define IRQ_PS2_KBD 0x16
#define IRQ_PS2_AUX 0x17
#define IRQ_DMA 0x18
#define IRQ_DMAERR 0x19
#define IRQ_TIMER0 0x1a
#define IRQ_TIMER1 0x1b
#define IRQ_TIMER2 0x1c
#define IRQ_TIMER3 0x1d
#define IRQ_RTC 0x1e
#define IRQ_RTCAlarm 0x1f
#define IRQ_GPIO0 0x20
#define IRQ_GPIO1 0x21
#define IRQ_GPIO2 0x22
#define IRQ_GPIO3 0x23
#define IRQ_GPIO4 0x24
#define IRQ_GPIO5 0x25
#define IRQ_GPIO6 0x26
#define IRQ_GPIO7 0x27
#define IRQ_GPIO8 0x28
#define IRQ_GPIO9 0x29
#define IRQ_GPIO10 0x2a
#define IRQ_GPIO11 0x2b
#define IRQ_GPIO12 0x2c
#define IRQ_GPIO13 0x2d
#define IRQ_GPIO14 0x2e
#define IRQ_GPIO15 0x2f
#define IRQ_GPIO16 0x30
#define IRQ_GPIO17 0x31
#define IRQ_GPIO18 0x32
#define IRQ_GPIO19 0x33
#define IRQ_GPIO20 0x34
#define IRQ_GPIO21 0x35
#define IRQ_GPIO22 0x36
#define IRQ_GPIO23 0x37
#define IRQ_GPIO24 0x38
#define IRQ_GPIO25 0x39
#define IRQ_GPIO26 0x3a
#define IRQ_GPIO27 0x3b
#ifdef CONFIG_ARCH_FPGA
#define IRQ_PCIINTA IRQ_GPIOLOW2
#define IRQ_PCIINTB IRQ_GPIOLOW1
#define IRQ_PCIINTC IRQ_GPIOLOW0
#define IRQ_PCIINTD IRQ_GPIOLOW6
#endif
#if defined(CONFIG_PUV3_DB0913) || defined(CONFIG_PUV3_NB0916) \
|| defined(CONFIG_PUV3_SMW0919)
#define IRQ_PCIINTA IRQ_GPIOLOW1
#define IRQ_PCIINTB IRQ_GPIOLOW2
#define IRQ_PCIINTC IRQ_GPIOLOW3
#define IRQ_PCIINTD IRQ_GPIOLOW4
#endif
#define IRQ_SD_CD IRQ_GPIO6 /* falling or rising trigger */
#ifndef __ASSEMBLY__
struct pt_regs;
extern void asm_do_IRQ(unsigned int, struct pt_regs *);
#endif
#endif

View File

@ -0,0 +1,53 @@
/*
* linux/arch/unicore32/include/asm/irqflags.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_IRQFLAGS_H__
#define __UNICORE_IRQFLAGS_H__
#ifdef __KERNEL__
#include <asm/ptrace.h>
#define ARCH_IRQ_DISABLED (PRIV_MODE | PSR_I_BIT)
#define ARCH_IRQ_ENABLED (PRIV_MODE)
/*
* Save the current interrupt enable state.
*/
static inline unsigned long arch_local_save_flags(void)
{
unsigned long temp;
asm volatile("mov %0, asr" : "=r" (temp) : : "memory", "cc");
return temp & PSR_c;
}
/*
* restore saved IRQ state
*/
static inline void arch_local_irq_restore(unsigned long flags)
{
unsigned long temp;
asm volatile(
"mov %0, asr\n"
"mov.a asr, %1\n"
"mov.f asr, %0"
: "=&r" (temp)
: "r" (flags)
: "memory", "cc");
}
#include <asm-generic/irqflags.h>
#endif
#endif

View File

@ -0,0 +1,22 @@
/*
* linux/arch/unicore32/include/asm/linkage.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_LINKAGE_H__
#define __UNICORE_LINKAGE_H__
#define __ALIGN .align 0
#define __ALIGN_STR ".align 0"
#define ENDPROC(name) \
.type name, %function; \
END(name)
#endif

View File

@ -0,0 +1,46 @@
/*
* linux/arch/unicore32/include/asm/memblock.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_MEMBLOCK_H__
#define __UNICORE_MEMBLOCK_H__
/*
* Memory map description
*/
# define NR_BANKS 8
struct membank {
unsigned long start;
unsigned long size;
unsigned int highmem;
};
struct meminfo {
int nr_banks;
struct membank bank[NR_BANKS];
};
extern struct meminfo meminfo;
#define for_each_bank(iter, mi) \
for (iter = 0; iter < (mi)->nr_banks; iter++)
#define bank_pfn_start(bank) __phys_to_pfn((bank)->start)
#define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size)
#define bank_pfn_size(bank) ((bank)->size >> PAGE_SHIFT)
#define bank_phys_start(bank) ((bank)->start)
#define bank_phys_end(bank) ((bank)->start + (bank)->size)
#define bank_phys_size(bank) ((bank)->size)
extern void uc32_memblock_init(struct meminfo *);
#endif

View File

@ -0,0 +1,123 @@
/*
* linux/arch/unicore32/include/asm/memory.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Note: this file should not be included by non-asm/.h files
*/
#ifndef __UNICORE_MEMORY_H__
#define __UNICORE_MEMORY_H__
#include <linux/compiler.h>
#include <linux/const.h>
#include <asm/sizes.h>
#include <mach/memory.h>
/*
* Allow for constants defined here to be used from assembly code
* by prepending the UL suffix only with actual C code compilation.
*/
#define UL(x) _AC(x, UL)
/*
* PAGE_OFFSET - the virtual address of the start of the kernel image
* TASK_SIZE - the maximum size of a user space task.
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
*/
#define PAGE_OFFSET UL(0xC0000000)
#define TASK_SIZE (PAGE_OFFSET - UL(0x41000000))
#define TASK_UNMAPPED_BASE (PAGE_OFFSET / 3)
/*
* The module space lives between the addresses given by TASK_SIZE
* and PAGE_OFFSET - it must be within 32MB of the kernel text.
*/
#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
#if TASK_SIZE > MODULES_VADDR
#error Top of user space clashes with start of module space
#endif
#define MODULES_END (PAGE_OFFSET)
/*
* Allow 16MB-aligned ioremap pages
*/
#define IOREMAP_MAX_ORDER 24
/*
* Physical vs virtual RAM address space conversion. These are
* private definitions which should NOT be used outside memory.h
* files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
*/
#ifndef __virt_to_phys
#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
#endif
/*
* Convert a physical address to a Page Frame Number and back
*/
#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
/*
* Convert a page to/from a physical address
*/
#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page)))
#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys)))
#ifndef __ASSEMBLY__
#ifndef arch_adjust_zones
#define arch_adjust_zones(size, holes) do { } while (0)
#endif
/*
* PFNs are used to describe any physical page; this means
* PFN 0 == physical address 0.
*
* This is the PFN of the first RAM page in the kernel
* direct-mapped view. We assume this is the first page
* of RAM in the mem_map as well.
*/
#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
/*
* Drivers should NOT use these either.
*/
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
/*
* Conversion between a struct page and a physical address.
*
* Note: when converting an unknown physical address to a
* struct page, the resulting pointer must be validated
* using VALID_PAGE(). It must return an invalid struct page
* for any physical address not corresponding to a system
* RAM address.
*
* page_to_pfn(page) convert a struct page * to a PFN number
* pfn_to_page(pfn) convert a _valid_ PFN number to struct page *
*
* virt_to_page(k) convert a _valid_ virtual address to struct page *
* virt_addr_valid(k) indicates whether a virtual address is valid
*/
#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && \
(unsigned long)(kaddr) < (unsigned long)high_memory)
#endif
#include <asm-generic/memory_model.h>
#endif

View File

@ -0,0 +1,17 @@
/*
* linux/arch/unicore32/include/asm/mmu.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_MMU_H__
#define __UNICORE_MMU_H__
typedef unsigned long mm_context_t;
#endif

View File

@ -0,0 +1,87 @@
/*
* linux/arch/unicore32/include/asm/mmu_context.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_MMU_CONTEXT_H__
#define __UNICORE_MMU_CONTEXT_H__
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/io.h>
#include <asm/cacheflush.h>
#include <asm/cpu-single.h>
#define init_new_context(tsk, mm) 0
#define destroy_context(mm) do { } while (0)
/*
* This is called when "tsk" is about to enter lazy TLB mode.
*
* mm: describes the currently active mm context
* tsk: task which is entering lazy tlb
* cpu: cpu number which is entering lazy tlb
*
* tsk->mm will be NULL
*/
static inline void
enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}
/*
* This is the actual mm switch as far as the scheduler
* is concerned. No registers are touched. We avoid
* calling the CPU specific function when the mm hasn't
* actually changed.
*/
static inline void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
unsigned int cpu = smp_processor_id();
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
cpu_switch_mm(next->pgd, next);
}
#define deactivate_mm(tsk, mm) do { } while (0)
#define activate_mm(prev, next) switch_mm(prev, next, NULL)
/*
* We are inserting a "fake" vma for the user-accessible vector page so
* gdb and friends can get to it through ptrace and /proc/<pid>/mem.
* But we also want to remove it before the generic code gets to see it
* during process exit or the unmapping of it would cause total havoc.
* (the macro is used as remove_vma() is static to mm/mmap.c)
*/
#define arch_exit_mmap(mm) \
do { \
struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
if (high_vma) { \
BUG_ON(high_vma->vm_next); /* it should be last */ \
if (high_vma->vm_prev) \
high_vma->vm_prev->vm_next = NULL; \
else \
mm->mmap = NULL; \
rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
mm->mmap_cache = NULL; \
mm->map_count--; \
remove_vma(high_vma); \
} \
} while (0)
static inline void arch_dup_mmap(struct mm_struct *oldmm,
struct mm_struct *mm)
{
}
#endif

View File

@ -0,0 +1,20 @@
/*
* linux/arch/unicore32/include/asm/mutex.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* UniCore optimized mutex locking primitives
*
* Please look into asm-generic/mutex-xchg.h for a formal definition.
*/
#ifndef __UNICORE_MUTEX_H__
#define __UNICORE_MUTEX_H__
# include <asm-generic/mutex-xchg.h>
#endif

View File

@ -0,0 +1,80 @@
/*
* linux/arch/unicore32/include/asm/page.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PAGE_H__
#define __UNICORE_PAGE_H__
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#ifndef __ASSEMBLY__
struct page;
struct vm_area_struct;
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern void copy_page(void *to, const void *from);
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte)
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) })
#define __pgd(x) ((pgd_t) { (x) })
#define __pgprot(x) ((pgprot_t) { (x) })
#else
/*
* .. while these make it easier on the compiler
*/
typedef unsigned long pte_t;
typedef unsigned long pgd_t;
typedef unsigned long pgprot_t;
#define pte_val(x) (x)
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
#define __pte(x) (x)
#define __pgd(x) (x)
#define __pgprot(x) (x)
#endif /* STRICT_MM_TYPECHECKS */
typedef struct page *pgtable_t;
extern int pfn_valid(unsigned long);
#include <asm/memory.h>
#endif /* !__ASSEMBLY__ */
#define VM_DATA_DEFAULT_FLAGS \
(VM_READ | VM_WRITE | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#include <asm-generic/getorder.h>
#endif

View File

@ -0,0 +1,46 @@
/*
* linux/arch/unicore32/include/asm/pci.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PCI_H__
#define __UNICORE_PCI_H__
#ifdef __KERNEL__
#include <asm-generic/pci-dma-compat.h>
#include <asm-generic/pci.h>
#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
static inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
}
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
/* We don't do dynamic PCI IRQ allocation */
}
#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
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
#endif /* __KERNEL__ */
#endif

View File

@ -0,0 +1,110 @@
/*
* linux/arch/unicore32/include/asm/pgalloc.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PGALLOC_H__
#define __UNICORE_PGALLOC_H__
#include <asm/pgtable-hwdef.h>
#include <asm/processor.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#define check_pgt_cache() do { } while (0)
#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
extern pgd_t *get_pgd_slow(struct mm_struct *mm);
extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
#define pgd_alloc(mm) get_pgd_slow(mm)
#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
/*
* Allocate one PTE table.
*/
static inline pte_t *
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
{
pte_t *pte;
pte = (pte_t *)__get_free_page(PGALLOC_GFP);
if (pte)
clean_dcache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
return pte;
}
static inline pgtable_t
pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
struct page *pte;
pte = alloc_pages(PGALLOC_GFP, 0);
if (pte) {
if (!PageHighMem(pte)) {
void *page = page_address(pte);
clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t));
}
pgtable_page_ctor(pte);
}
return pte;
}
/*
* Free one PTE table.
*/
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
if (pte)
free_page((unsigned long)pte);
}
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
{
pgtable_page_dtor(pte);
__free_page(pte);
}
static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
{
set_pmd(pmdp, __pmd(pmdval));
flush_pmd_entry(pmdp);
}
/*
* Populate the pmdp entry with a pointer to the pte. This pmd is part
* of the mm address space.
*/
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
unsigned long pte_ptr = (unsigned long)ptep;
/*
* The pmd must be loaded with the physical
* address of the PTE table
*/
__pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
}
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
__pmd_populate(pmdp,
page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
}
#define pmd_pgtable(pmd) pmd_page(pmd)
#endif

View File

@ -0,0 +1,55 @@
/*
* linux/arch/unicore32/include/asm/pgtable-hwdef.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PGTABLE_HWDEF_H__
#define __UNICORE_PGTABLE_HWDEF_H__
/*
* Hardware page table definitions.
*
* + Level 1 descriptor (PMD)
* - common
*/
#define PMD_TYPE_MASK (3 << 0)
#define PMD_TYPE_TABLE (0 << 0)
/*#define PMD_TYPE_LARGE (1 << 0) */
#define PMD_TYPE_INVALID (2 << 0)
#define PMD_TYPE_SECT (3 << 0)
#define PMD_PRESENT (1 << 2)
#define PMD_YOUNG (1 << 3)
/*#define PMD_SECT_DIRTY (1 << 4) */
#define PMD_SECT_CACHEABLE (1 << 5)
#define PMD_SECT_EXEC (1 << 6)
#define PMD_SECT_WRITE (1 << 7)
#define PMD_SECT_READ (1 << 8)
/*
* + Level 2 descriptor (PTE)
* - common
*/
#define PTE_TYPE_MASK (3 << 0)
#define PTE_TYPE_SMALL (0 << 0)
#define PTE_TYPE_MIDDLE (1 << 0)
#define PTE_TYPE_LARGE (2 << 0)
#define PTE_TYPE_INVALID (3 << 0)
#define PTE_PRESENT (1 << 2)
#define PTE_FILE (1 << 3) /* only when !PRESENT */
#define PTE_YOUNG (1 << 3)
#define PTE_DIRTY (1 << 4)
#define PTE_CACHEABLE (1 << 5)
#define PTE_EXEC (1 << 6)
#define PTE_WRITE (1 << 7)
#define PTE_READ (1 << 8)
#endif

View File

@ -0,0 +1,317 @@
/*
* linux/arch/unicore32/include/asm/pgtable.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PGTABLE_H__
#define __UNICORE_PGTABLE_H__
#include <asm-generic/pgtable-nopmd.h>
#include <asm/cpu-single.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 8MB value just means that there will be a 8MB "hole" after the
* physical memory until the kernel virtual memory starts. That means that
* any out-of-bounds memory accesses will hopefully be caught.
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*
* Note that platforms may override VMALLOC_START, but they must provide
* VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space,
* which may not overlap IO space.
*/
#ifndef VMALLOC_START
#define VMALLOC_OFFSET SZ_8M
#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) \
& ~(VMALLOC_OFFSET-1))
#define VMALLOC_END (0xff000000UL)
#endif
#define PTRS_PER_PTE 1024
#define PTRS_PER_PGD 1024
/*
* PGDIR_SHIFT determines what a third-level page table entry can map
*/
#define PGDIR_SHIFT 22
#ifndef __ASSEMBLY__
extern void __pte_error(const char *file, int line, unsigned long val);
extern void __pgd_error(const char *file, int line, unsigned long val);
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
#endif /* !__ASSEMBLY__ */
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* This is the lowest virtual address we can permit any user space
* mapping to be mapped at. This is particularly important for
* non-high vector CPUs.
*/
#define FIRST_USER_ADDRESS PAGE_SIZE
#define FIRST_USER_PGD_NR 1
#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
/*
* section address mask and size definitions.
*/
#define SECTION_SHIFT 22
#define SECTION_SIZE (1UL << SECTION_SHIFT)
#define SECTION_MASK (~(SECTION_SIZE-1))
#ifndef __ASSEMBLY__
/*
* The pgprot_* and protection_map entries will be fixed up in runtime
* to include the cachable bits based on memory policy, as well as any
* architecture dependent bits.
*/
#define _PTE_DEFAULT (PTE_PRESENT | PTE_YOUNG | PTE_CACHEABLE)
extern pgprot_t pgprot_user;
extern pgprot_t pgprot_kernel;
#define PAGE_NONE pgprot_user
#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user | PTE_READ \
| PTE_WRITE)
#define PAGE_SHARED_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
| PTE_WRITE \
| PTE_EXEC)
#define PAGE_COPY __pgprot(pgprot_val(pgprot_user | PTE_READ)
#define PAGE_COPY_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
| PTE_EXEC)
#define PAGE_READONLY __pgprot(pgprot_val(pgprot_user | PTE_READ)
#define PAGE_READONLY_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
| PTE_EXEC)
#define PAGE_KERNEL pgprot_kernel
#define PAGE_KERNEL_EXEC __pgprot(pgprot_val(pgprot_kernel | PTE_EXEC))
#define __PAGE_NONE __pgprot(_PTE_DEFAULT)
#define __PAGE_SHARED __pgprot(_PTE_DEFAULT | PTE_READ \
| PTE_WRITE)
#define __PAGE_SHARED_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
| PTE_WRITE \
| PTE_EXEC)
#define __PAGE_COPY __pgprot(_PTE_DEFAULT | PTE_READ)
#define __PAGE_COPY_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
| PTE_EXEC)
#define __PAGE_READONLY __pgprot(_PTE_DEFAULT | PTE_READ)
#define __PAGE_READONLY_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
| PTE_EXEC)
#endif /* __ASSEMBLY__ */
/*
* The table below defines the page protection levels that we insert into our
* Linux page table version. These get translated into the best that the
* architecture can perform. Note that on UniCore hardware:
* 1) We cannot do execute protection
* 2) If we could do execute protection, then read is implied
* 3) write implies read permissions
*/
#define __P000 __PAGE_NONE
#define __P001 __PAGE_READONLY
#define __P010 __PAGE_COPY
#define __P011 __PAGE_COPY
#define __P100 __PAGE_READONLY_EXEC
#define __P101 __PAGE_READONLY_EXEC
#define __P110 __PAGE_COPY_EXEC
#define __P111 __PAGE_COPY_EXEC
#define __S000 __PAGE_NONE
#define __S001 __PAGE_READONLY
#define __S010 __PAGE_SHARED
#define __S011 __PAGE_SHARED
#define __S100 __PAGE_READONLY_EXEC
#define __S101 __PAGE_READONLY_EXEC
#define __S110 __PAGE_SHARED_EXEC
#define __S111 __PAGE_SHARED_EXEC
#ifndef __ASSEMBLY__
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
*/
extern struct page *empty_zero_page;
#define ZERO_PAGE(vaddr) (empty_zero_page)
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
#define pfn_pte(pfn, prot) (__pte(((pfn) << PAGE_SHIFT) \
| pgprot_val(prot)))
#define pte_none(pte) (!pte_val(pte))
#define pte_clear(mm, addr, ptep) set_pte(ptep, __pte(0))
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
#define pte_offset_kernel(dir, addr) (pmd_page_vaddr(*(dir)) \
+ __pte_index(addr))
#define pte_offset_map(dir, addr) (pmd_page_vaddr(*(dir)) \
+ __pte_index(addr))
#define pte_unmap(pte) do { } while (0)
#define set_pte(ptep, pte) cpu_set_pte(ptep, pte)
#define set_pte_at(mm, addr, ptep, pteval) \
do { \
set_pte(ptep, pteval); \
} while (0)
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
#define pte_present(pte) (pte_val(pte) & PTE_PRESENT)
#define pte_write(pte) (pte_val(pte) & PTE_WRITE)
#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & PTE_YOUNG)
#define pte_exec(pte) (pte_val(pte) & PTE_EXEC)
#define pte_special(pte) (0)
#define PTE_BIT_FUNC(fn, op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
PTE_BIT_FUNC(wrprotect, &= ~PTE_WRITE);
PTE_BIT_FUNC(mkwrite, |= PTE_WRITE);
PTE_BIT_FUNC(mkclean, &= ~PTE_DIRTY);
PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY);
PTE_BIT_FUNC(mkold, &= ~PTE_YOUNG);
PTE_BIT_FUNC(mkyoung, |= PTE_YOUNG);
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
/*
* Mark the prot value as uncacheable.
*/
#define pgprot_noncached(prot) \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pgprot_writecombine(prot) \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pgprot_dmacoherent(prot) \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd) & PMD_PRESENT)
#define pmd_bad(pmd) (((pmd_val(pmd) & \
(PMD_PRESENT | PMD_TYPE_MASK)) \
!= (PMD_PRESENT | PMD_TYPE_TABLE)))
#define set_pmd(pmdpd, pmdval) \
do { \
*(pmdpd) = pmdval; \
} while (0)
#define pmd_clear(pmdp) \
do { \
set_pmd(pmdp, __pmd(0));\
clean_pmd_entry(pmdp); \
} while (0)
#define pmd_page_vaddr(pmd) ((pte_t *)__va(pmd_val(pmd) & PAGE_MASK))
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
/* to find an entry in a page-table-directory */
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
/* Find an entry in the third-level page table.. */
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
const unsigned long mask = PTE_EXEC | PTE_WRITE | PTE_READ;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte;
}
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
/*
* Encode and decode a swap entry. Swap entries are stored in the Linux
* page tables as follows:
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* <--------------- offset --------------> <--- type --> 0 0 0 0 0
*
* This gives us up to 127 swap files and 32GB per swap file. Note that
* the offset field is always non-zero.
*/
#define __SWP_TYPE_SHIFT 5
#define __SWP_TYPE_BITS 7
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) \
& __SWP_TYPE_MASK)
#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
#define __swp_entry(type, offset) ((swp_entry_t) { \
((type) << __SWP_TYPE_SHIFT) | \
((offset) << __SWP_OFFSET_SHIFT) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
/*
* It is an error for the kernel to have more swap files than we can
* encode in the PTEs. This ensures that we know when MAX_SWAPFILES
* is increased beyond what we presently support.
*/
#define MAX_SWAPFILES_CHECK() \
BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
/*
* Encode and decode a file entry. File entries are stored in the Linux
* page tables as follows:
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* <----------------------- offset ----------------------> 1 0 0 0
*/
#define pte_file(pte) (pte_val(pte) & PTE_FILE)
#define pte_to_pgoff(x) (pte_val(x) >> 4)
#define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE)
#define PTE_FILE_MAX_BITS 28
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
/* FIXME: this is not correct */
#define kern_addr_valid(addr) (1)
#include <asm-generic/pgtable.h>
/*
* remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
#define io_remap_pfn_range(vma, from, pfn, size, prot) \
remap_pfn_range(vma, from, pfn, size, prot)
#define pgtable_cache_init() do { } while (0)
#endif /* !__ASSEMBLY__ */
#endif /* __UNICORE_PGTABLE_H__ */

View File

@ -0,0 +1,92 @@
/*
* linux/arch/unicore32/include/asm/processor.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PROCESSOR_H__
#define __UNICORE_PROCESSOR_H__
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l; })
#ifdef __KERNEL__
#include <asm/ptrace.h>
#include <asm/types.h>
#ifdef __KERNEL__
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX TASK_SIZE
#endif
struct debug_entry {
u32 address;
u32 insn;
};
struct debug_info {
int nsaved;
struct debug_entry bp[2];
};
struct thread_struct {
/* fault info */
unsigned long address;
unsigned long trap_no;
unsigned long error_code;
/* debugging */
struct debug_info debug;
};
#define INIT_THREAD { }
#define start_thread(regs, pc, sp) \
({ \
unsigned long *stack = (unsigned long *)sp; \
set_fs(USER_DS); \
memset(regs->uregs, 0, sizeof(regs->uregs)); \
regs->UCreg_asr = USER_MODE; \
regs->UCreg_pc = pc & ~1; /* pc */ \
regs->UCreg_sp = sp; /* sp */ \
regs->UCreg_02 = stack[2]; /* r2 (envp) */ \
regs->UCreg_01 = stack[1]; /* r1 (argv) */ \
regs->UCreg_00 = stack[0]; /* r0 (argc) */ \
})
/* Forward declaration, a strange C thing */
struct task_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
/*
* Create a new kernel thread
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->UCreg_pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->UCreg_sp)
#endif
#endif /* __UNICORE_PROCESSOR_H__ */

View File

@ -0,0 +1,133 @@
/*
* linux/arch/unicore32/include/asm/ptrace.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_PTRACE_H__
#define __UNICORE_PTRACE_H__
#define PTRACE_GET_THREAD_AREA 22
/*
* PSR bits
*/
#define USER_MODE 0x00000010
#define REAL_MODE 0x00000011
#define INTR_MODE 0x00000012
#define PRIV_MODE 0x00000013
#define ABRT_MODE 0x00000017
#define EXTN_MODE 0x0000001b
#define SUSR_MODE 0x0000001f
#define MODE_MASK 0x0000001f
#define PSR_R_BIT 0x00000040
#define PSR_I_BIT 0x00000080
#define PSR_V_BIT 0x10000000
#define PSR_C_BIT 0x20000000
#define PSR_Z_BIT 0x40000000
#define PSR_S_BIT 0x80000000
/*
* Groups of PSR bits
*/
#define PSR_f 0xff000000 /* Flags */
#define PSR_c 0x000000ff /* Control */
#ifndef __ASSEMBLY__
/*
* This struct defines the way the registers are stored on the
* stack during a system call. Note that sizeof(struct pt_regs)
* has to be a multiple of 8.
*/
struct pt_regs {
unsigned long uregs[34];
};
#define UCreg_asr uregs[32]
#define UCreg_pc uregs[31]
#define UCreg_lr uregs[30]
#define UCreg_sp uregs[29]
#define UCreg_ip uregs[28]
#define UCreg_fp uregs[27]
#define UCreg_26 uregs[26]
#define UCreg_25 uregs[25]
#define UCreg_24 uregs[24]
#define UCreg_23 uregs[23]
#define UCreg_22 uregs[22]
#define UCreg_21 uregs[21]
#define UCreg_20 uregs[20]
#define UCreg_19 uregs[19]
#define UCreg_18 uregs[18]
#define UCreg_17 uregs[17]
#define UCreg_16 uregs[16]
#define UCreg_15 uregs[15]
#define UCreg_14 uregs[14]
#define UCreg_13 uregs[13]
#define UCreg_12 uregs[12]
#define UCreg_11 uregs[11]
#define UCreg_10 uregs[10]
#define UCreg_09 uregs[9]
#define UCreg_08 uregs[8]
#define UCreg_07 uregs[7]
#define UCreg_06 uregs[6]
#define UCreg_05 uregs[5]
#define UCreg_04 uregs[4]
#define UCreg_03 uregs[3]
#define UCreg_02 uregs[2]
#define UCreg_01 uregs[1]
#define UCreg_00 uregs[0]
#define UCreg_ORIG_00 uregs[33]
#ifdef __KERNEL__
#define user_mode(regs) \
(processor_mode(regs) == USER_MODE)
#define processor_mode(regs) \
((regs)->UCreg_asr & MODE_MASK)
#define interrupts_enabled(regs) \
(!((regs)->UCreg_asr & PSR_I_BIT))
#define fast_interrupts_enabled(regs) \
(!((regs)->UCreg_asr & PSR_R_BIT))
/* Are the current registers suitable for user mode?
* (used to maintain security in signal handlers)
*/
static inline int valid_user_regs(struct pt_regs *regs)
{
unsigned long mode = regs->UCreg_asr & MODE_MASK;
/*
* Always clear the R (REAL) bits
*/
regs->UCreg_asr &= ~(PSR_R_BIT);
if ((regs->UCreg_asr & PSR_I_BIT) == 0) {
if (mode == USER_MODE)
return 1;
}
/*
* Force ASR to something logical...
*/
regs->UCreg_asr &= PSR_f | USER_MODE;
return 0;
}
#define instruction_pointer(regs) ((regs)->UCreg_pc)
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif

View File

@ -0,0 +1,29 @@
/*
* linux/arch/unicore32/include/asm/sigcontext.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_SIGCONTEXT_H__
#define __UNICORE_SIGCONTEXT_H__
#include <asm/ptrace.h>
/*
* Signal context structure - contains all info to do with the state
* before the signal handler was invoked. Note: only add new entries
* to the end of the structure.
*/
struct sigcontext {
unsigned long trap_no;
unsigned long error_code;
unsigned long oldmask;
unsigned long fault_address;
struct pt_regs regs;
};
#endif

View File

@ -0,0 +1,31 @@
/*
* linux/arch/unicore32/include/asm/stacktrace.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_STACKTRACE_H__
#define __UNICORE_STACKTRACE_H__
struct stackframe {
unsigned long fp;
unsigned long sp;
unsigned long lr;
unsigned long pc;
};
#ifdef CONFIG_FRAME_POINTER
extern int unwind_frame(struct stackframe *frame);
#else
#define unwind_frame(f) (-EINVAL)
#endif
extern void walk_stackframe(struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data);
#endif /* __UNICORE_STACKTRACE_H__ */

View File

@ -0,0 +1,38 @@
/*
* linux/arch/unicore32/include/asm/string.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_STRING_H__
#define __UNICORE_STRING_H__
/*
* We don't do inline string functions, since the
* optimised inline asm versions are not small.
*/
#define __HAVE_ARCH_STRRCHR
extern char *strrchr(const char *s, int c);
#define __HAVE_ARCH_STRCHR
extern char *strchr(const char *s, int c);
#define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMMOVE
extern void *memmove(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMCHR
extern void *memchr(const void *, int, __kernel_size_t);
#define __HAVE_ARCH_MEMSET
extern void *memset(void *, int, __kernel_size_t);
#endif

View File

@ -0,0 +1,30 @@
/*
* linux/arch/unicore32/include/asm/suspend.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_SUSPEND_H__
#define __UNICORE_SUSPEND_H__
#ifndef __ASSEMBLY__
static inline int arch_prepare_suspend(void) { return 0; }
#include <asm/ptrace.h>
struct swsusp_arch_regs {
struct cpu_context_save cpu_context; /* cpu context */
#ifdef CONFIG_UNICORE_FPU_F64
struct fp_state fpstate __attribute__((aligned(8)));
#endif
};
#endif
#endif /* __UNICORE_SUSPEND_H__ */

View File

@ -0,0 +1,161 @@
/*
* linux/arch/unicore32/include/asm/system.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_SYSTEM_H__
#define __UNICORE_SYSTEM_H__
#ifdef __KERNEL__
/*
* CR1 bits (CP#0 CR1)
*/
#define CR_M (1 << 0) /* MMU enable */
#define CR_A (1 << 1) /* Alignment abort enable */
#define CR_D (1 << 2) /* Dcache enable */
#define CR_I (1 << 3) /* Icache enable */
#define CR_B (1 << 4) /* Dcache write mechanism: write back */
#define CR_T (1 << 5) /* Burst enable */
#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
#include <linux/irqflags.h>
struct thread_info;
struct task_struct;
struct pt_regs;
void die(const char *msg, struct pt_regs *regs, int err);
struct siginfo;
void uc32_notify_die(const char *str, struct pt_regs *regs,
struct siginfo *info, unsigned long err, unsigned long trap);
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
int sig, int code, const char *name);
#define xchg(ptr, x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
extern asmlinkage void __backtrace(void);
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
struct mm_struct;
extern void show_pte(struct mm_struct *mm, unsigned long addr);
extern void __show_regs(struct pt_regs *);
extern int cpu_architecture(void);
extern void cpu_init(void);
#define vectors_high() (cr_alignment & CR_V)
#define isb() __asm__ __volatile__ ("" : : : "memory")
#define dsb() __asm__ __volatile__ ("" : : : "memory")
#define dmb() __asm__ __volatile__ ("" : : : "memory")
#define mb() barrier()
#define rmb() barrier()
#define wmb() barrier()
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#define read_barrier_depends() do { } while (0)
#define smp_read_barrier_depends() do { } while (0)
#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
extern unsigned long cr_no_alignment; /* defined in entry-unicore.S */
extern unsigned long cr_alignment; /* defined in entry-unicore.S */
static inline unsigned int get_cr(void)
{
unsigned int val;
asm("movc %0, p0.c1, #0" : "=r" (val) : : "cc");
return val;
}
static inline void set_cr(unsigned int val)
{
asm volatile("movc p0.c1, %0, #0 @set CR"
: : "r" (val) : "cc");
isb();
}
extern void adjust_cr(unsigned long mask, unsigned long set);
/*
* switch_to(prev, next) should switch from task `prev' to `next'
* `prev' will never be the same as `next'. schedule() itself
* contains the memory barrier to tell GCC not to cache `current'.
*/
extern struct task_struct *__switch_to(struct task_struct *,
struct thread_info *, struct thread_info *);
extern void panic(const char *fmt, ...);
#define switch_to(prev, next, last) \
do { \
last = __switch_to(prev, \
task_thread_info(prev), task_thread_info(next)); \
} while (0)
static inline unsigned long
__xchg(unsigned long x, volatile void *ptr, int size)
{
unsigned long ret;
switch (size) {
case 1:
asm volatile("@ __xchg1\n"
" swapb %0, %1, [%2]"
: "=&r" (ret)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
case 4:
asm volatile("@ __xchg4\n"
" swapw %0, %1, [%2]"
: "=&r" (ret)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
default:
panic("xchg: bad data size: ptr 0x%p, size %d\n",
ptr, size);
}
return ret;
}
#include <asm-generic/cmpxchg-local.h>
/*
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
* them available.
*/
#define cmpxchg_local(ptr, o, n) \
((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
(unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
#define cmpxchg64_local(ptr, o, n) \
__cmpxchg64_local_generic((ptr), (o), (n))
#include <asm-generic/cmpxchg.h>
#endif /* __ASSEMBLY__ */
#define arch_align_stack(x) (x)
#endif /* __KERNEL__ */
#endif

View File

@ -0,0 +1,154 @@
/*
* linux/arch/unicore32/include/asm/thread_info.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_THREAD_INFO_H__
#define __UNICORE_THREAD_INFO_H__
#ifdef __KERNEL__
#include <linux/compiler.h>
#include <asm/fpstate.h>
#define THREAD_SIZE_ORDER 1
#define THREAD_SIZE 8192
#define THREAD_START_SP (THREAD_SIZE - 8)
#ifndef __ASSEMBLY__
struct task_struct;
struct exec_domain;
#include <asm/types.h>
typedef struct {
unsigned long seg;
} mm_segment_t;
struct cpu_context_save {
__u32 r4;
__u32 r5;
__u32 r6;
__u32 r7;
__u32 r8;
__u32 r9;
__u32 r10;
__u32 r11;
__u32 r12;
__u32 r13;
__u32 r14;
__u32 r15;
__u32 r16;
__u32 r17;
__u32 r18;
__u32 r19;
__u32 r20;
__u32 r21;
__u32 r22;
__u32 r23;
__u32 r24;
__u32 r25;
__u32 r26;
__u32 fp;
__u32 sp;
__u32 pc;
};
/*
* low level task data that entry.S needs immediate access to.
* __switch_to() assumes cpu_context follows immediately after cpu_domain.
*/
struct thread_info {
unsigned long flags; /* low level flags */
int preempt_count; /* 0 => preemptable */
/* <0 => bug */
mm_segment_t addr_limit; /* address limit */
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
__u32 cpu; /* cpu */
struct cpu_context_save cpu_context; /* cpu context */
__u32 syscall; /* syscall number */
__u8 used_cp[16]; /* thread used copro */
#ifdef CONFIG_UNICORE_FPU_F64
struct fp_state fpstate __attribute__((aligned(8)));
#endif
struct restart_block restart_block;
};
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.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) __attribute_const__;
static inline struct thread_info *current_thread_info(void)
{
register unsigned long sp asm ("sp");
return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
}
#define thread_saved_pc(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
#define thread_saved_sp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
#define thread_saved_fp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
#endif
/*
* We use bit 30 of the preempt_count to indicate that kernel
* preemption is occurring. See <asm/hardirq.h>.
*/
#define PREEMPT_ACTIVE 0x40000000
/*
* thread information flags:
* TIF_SYSCALL_TRACE - syscall trace active
* TIF_SIGPENDING - signal pending
* TIF_NEED_RESCHED - rescheduling necessary
* TIF_NOTIFY_RESUME - callback before returning to user
*/
#define TIF_SIGPENDING 0
#define TIF_NEED_RESCHED 1
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
#define TIF_SYSCALL_TRACE 8
#define TIF_MEMDIE 18
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
/*
* Change these and you break ASM code in entry-common.S
*/
#define _TIF_WORK_MASK 0x000000ff
#endif /* __KERNEL__ */
#endif /* __UNICORE_THREAD_INFO_H__ */

View File

@ -0,0 +1,34 @@
/*
* linux/arch/unicore32/include/asm/timex.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_TIMEX_H__
#define __UNICORE_TIMEX_H__
#ifdef CONFIG_ARCH_FPGA
/* in FPGA, APB clock is 33M, and OST clock is 32K, */
/* so, 1M is selected for timer interrupt correctly */
#define CLOCK_TICK_RATE (32*1024)
#endif
#if defined(CONFIG_PUV3_DB0913) \
|| defined(CONFIG_PUV3_NB0916) \
|| defined(CONFIG_PUV3_SMW0919)
#define CLOCK_TICK_RATE (14318000)
#endif
#include <asm-generic/timex.h>
#endif

View File

@ -0,0 +1,28 @@
/*
* linux/arch/unicore32/include/asm/tlb.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_TLB_H__
#define __UNICORE_TLB_H__
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
#define __pte_free_tlb(tlb, pte, addr) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), (pte)); \
} while (0)
#include <asm-generic/tlb.h>
#endif

View File

@ -0,0 +1,195 @@
/*
* linux/arch/unicore32/include/asm/tlbflush.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_TLBFLUSH_H__
#define __UNICORE_TLBFLUSH_H__
#ifndef __ASSEMBLY__
#include <linux/sched.h>
extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long,
struct vm_area_struct *);
extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
/*
* TLB Management
* ==============
*
* The arch/unicore/mm/tlb-*.S files implement these methods.
*
* The TLB specific code is expected to perform whatever tests it
* needs to determine if it should invalidate the TLB for each
* call. Start addresses are inclusive and end addresses are
* exclusive; it is safe to round these addresses down.
*
* flush_tlb_all()
*
* Invalidate the entire TLB.
*
* flush_tlb_mm(mm)
*
* Invalidate all TLB entries in a particular address
* space.
* - mm - mm_struct describing address space
*
* flush_tlb_range(mm,start,end)
*
* Invalidate a range of TLB entries in the specified
* address space.
* - mm - mm_struct describing address space
* - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned)
*
* flush_tlb_page(vaddr,vma)
*
* Invalidate the specified page in the specified address range.
* - vaddr - virtual address (may not be aligned)
* - vma - vma_struct describing address range
*
* flush_kern_tlb_page(kaddr)
*
* Invalidate the TLB entry for the specified page. The address
* will be in the kernels virtual memory space. Current uses
* only require the D-TLB to be invalidated.
* - kaddr - Kernel virtual memory address
*/
static inline void local_flush_tlb_all(void)
{
const int zero = 0;
/* TLB invalidate all */
asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (zero) : "cc");
}
static inline void local_flush_tlb_mm(struct mm_struct *mm)
{
const int zero = 0;
if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
/* TLB invalidate all */
asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (zero) : "cc");
}
put_cpu();
}
static inline void
local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
/* iTLB invalidate page */
asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (uaddr & PAGE_MASK) : "cc");
/* dTLB invalidate page */
asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (uaddr & PAGE_MASK) : "cc");
#else
/* TLB invalidate all */
asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (uaddr & PAGE_MASK) : "cc");
#endif
}
}
static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
{
#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
/* iTLB invalidate page */
asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (kaddr & PAGE_MASK) : "cc");
/* dTLB invalidate page */
asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (kaddr & PAGE_MASK) : "cc");
#else
/* TLB invalidate all */
asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (kaddr & PAGE_MASK) : "cc");
#endif
}
/*
* flush_pmd_entry
*
* Flush a PMD entry (word aligned, or double-word aligned) to
* RAM if the TLB for the CPU we are running on requires this.
* This is typically used when we are creating PMD entries.
*
* clean_pmd_entry
*
* Clean (but don't drain the write buffer) if the CPU requires
* these operations. This is typically used when we are removing
* PMD entries.
*/
static inline void flush_pmd_entry(pmd_t *pmd)
{
#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
/* flush dcache line, see dcacheline_flush in proc-macros.S */
asm("mov r1, %0 << #20\n"
"ldw r2, =_stext\n"
"add r2, r2, r1 >> #20\n"
"ldw r1, [r2+], #0x0000\n"
"ldw r1, [r2+], #0x1000\n"
"ldw r1, [r2+], #0x2000\n"
"ldw r1, [r2+], #0x3000\n"
: : "r" (pmd) : "r1", "r2");
#else
/* flush dcache all */
asm("movc p0.c5, %0, #14; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (pmd) : "cc");
#endif
}
static inline void clean_pmd_entry(pmd_t *pmd)
{
#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
/* clean dcache line */
asm("movc p0.c5, %0, #11; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (__pa(pmd) & ~(L1_CACHE_BYTES - 1)) : "cc");
#else
/* clean dcache all */
asm("movc p0.c5, %0, #10; nop; nop; nop; nop; nop; nop; nop; nop"
: : "r" (pmd) : "cc");
#endif
}
/*
* Convert calls to our calling convention.
*/
#define local_flush_tlb_range(vma, start, end) \
__cpu_flush_user_tlb_range(start, end, vma)
#define local_flush_tlb_kernel_range(s, e) \
__cpu_flush_kern_tlb_range(s, e)
#define flush_tlb_all local_flush_tlb_all
#define flush_tlb_mm local_flush_tlb_mm
#define flush_tlb_page local_flush_tlb_page
#define flush_tlb_kernel_page local_flush_tlb_kernel_page
#define flush_tlb_range local_flush_tlb_range
#define flush_tlb_kernel_range local_flush_tlb_kernel_range
/*
* if PG_dcache_clean is not set for the page, we need to ensure that any
* cache entries for the kernels virtual memory range are written
* back to the page.
*/
extern void update_mmu_cache(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep);
extern void do_bad_area(unsigned long addr, unsigned int fsr,
struct pt_regs *regs);
#endif
#endif

View File

@ -0,0 +1,21 @@
/*
* linux/arch/unicore32/include/asm/traps.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_TRAP_H__
#define __UNICORE_TRAP_H__
extern void __init early_trap_init(void);
extern void dump_backtrace_entry(unsigned long where,
unsigned long from, unsigned long frame);
extern void do_DataAbort(unsigned long addr, unsigned int fsr,
struct pt_regs *regs);
#endif

View File

@ -0,0 +1,47 @@
/*
* linux/arch/unicore32/include/asm/uaccess.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __UNICORE_UACCESS_H__
#define __UNICORE_UACCESS_H__
#include <linux/thread_info.h>
#include <linux/errno.h>
#include <asm/memory.h>
#include <asm/system.h>
#define __copy_from_user __copy_from_user
#define __copy_to_user __copy_to_user
#define __strncpy_from_user __strncpy_from_user
#define __strnlen_user __strnlen_user
#define __clear_user __clear_user
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
#define __user_ok(addr, size) (((size) <= TASK_SIZE) \
&& ((addr) <= TASK_SIZE - (size)))
#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
extern unsigned long __must_check
__copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __must_check
__clear_user(void __user *addr, unsigned long n);
extern unsigned long __must_check
__strncpy_from_user(char *to, const char __user *from, unsigned long count);
extern unsigned long
__strnlen_user(const char __user *s, long n);
#include <asm-generic/uaccess.h>
extern int fixup_exception(struct pt_regs *regs);
#endif /* __UNICORE_UACCESS_H__ */

View File

@ -0,0 +1,18 @@
/*
* linux/arch/unicore32/include/asm/unistd.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#if !defined(__UNICORE_UNISTD_H__) || defined(__SYSCALL)
#define __UNICORE_UNISTD_H__
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
#endif /* __UNICORE_UNISTD_H__ */

View File

@ -0,0 +1,108 @@
/*
* linux/arch/unicore32/include/mach/PKUnity.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
/* Be sure that virtual mapping is defined right */
#ifndef __MACH_PUV3_HARDWARE_H__
#error You must include hardware.h not PKUnity.h
#endif
#include "bitfield.h"
/*
* Memory Definitions
*/
#define PKUNITY_SDRAM_BASE 0x00000000 /* 0x00000000 - 0x7FFFFFFF 2GB */
#define PKUNITY_MMIO_BASE 0x80000000 /* 0x80000000 - 0xFFFFFFFF 2GB */
/*
* PKUNITY Memory Map Addresses: 0x0D000000 - 0x0EFFFFFF (32MB)
* 0x0D000000 - 0x0DFFFFFF 16MB: for UVC
* 0x0E000000 - 0x0EFFFFFF 16MB: for UNIGFX
*/
#define PKUNITY_UVC_MMAP_BASE 0x0D000000
#define PKUNITY_UVC_MMAP_SIZE 0x01000000 /* 16MB */
#define PKUNITY_UNIGFX_MMAP_BASE 0x0E000000
#define PKUNITY_UNIGFX_MMAP_SIZE 0x01000000 /* 16MB */
/*
* PKUNITY System Bus Addresses (PCI): 0x80000000 - 0xBFFFFFFF (1GB)
* 0x80000000 - 0x8000000B 12B PCI Configuration regs
* 0x80010000 - 0x80010250 592B PCI Bridge Base
* 0x80030000 - 0x8003FFFF 64KB PCI Legacy IO
* 0x90000000 - 0x97FFFFFF 128MB PCI AHB-PCI MEM-mapping
* 0x98000000 - 0x9FFFFFFF 128MB PCI PCI-AHB MEM-mapping
*/
#define PKUNITY_PCI_BASE io_p2v(0x80000000) /* 0x80000000 - 0xBFFFFFFF 1GB */
#include "regs-pci.h"
#define PKUNITY_PCICFG_BASE (PKUNITY_PCI_BASE + 0x0)
#define PKUNITY_PCIBRI_BASE (PKUNITY_PCI_BASE + 0x00010000)
#define PKUNITY_PCILIO_BASE (PKUNITY_PCI_BASE + 0x00030000)
#define PKUNITY_PCIMEM_BASE (PKUNITY_PCI_BASE + 0x10000000)
#define PKUNITY_PCIAHB_BASE (PKUNITY_PCI_BASE + 0x18000000)
/*
* PKUNITY System Bus Addresses (AHB): 0xC0000000 - 0xEDFFFFFF (640MB)
*/
#define PKUNITY_AHB_BASE io_p2v(0xC0000000)
/* AHB-0 is DDR2 SDRAM */
/* AHB-1 is PCI Space */
#define PKUNITY_ARBITER_BASE (PKUNITY_AHB_BASE + 0x000000) /* AHB-2 */
#define PKUNITY_DDR2CTRL_BASE (PKUNITY_AHB_BASE + 0x100000) /* AHB-3 */
#define PKUNITY_DMAC_BASE (PKUNITY_AHB_BASE + 0x200000) /* AHB-4 */
#include "regs-dmac.h"
#define PKUNITY_UMAL_BASE (PKUNITY_AHB_BASE + 0x300000) /* AHB-5 */
#include "regs-umal.h"
#define PKUNITY_USB_BASE (PKUNITY_AHB_BASE + 0x400000) /* AHB-6 */
#define PKUNITY_SATA_BASE (PKUNITY_AHB_BASE + 0x500000) /* AHB-7 */
#define PKUNITY_SMC_BASE (PKUNITY_AHB_BASE + 0x600000) /* AHB-8 */
/* AHB-9 is for APB bridge */
#define PKUNITY_MME_BASE (PKUNITY_AHB_BASE + 0x700000) /* AHB-10 */
#define PKUNITY_UNIGFX_BASE (PKUNITY_AHB_BASE + 0x800000) /* AHB-11 */
#include "regs-unigfx.h"
#define PKUNITY_NAND_BASE (PKUNITY_AHB_BASE + 0x900000) /* AHB-12 */
#include "regs-nand.h"
#define PKUNITY_H264D_BASE (PKUNITY_AHB_BASE + 0xA00000) /* AHB-13 */
#define PKUNITY_H264E_BASE (PKUNITY_AHB_BASE + 0xB00000) /* AHB-14 */
/*
* PKUNITY Peripheral Bus Addresses (APB): 0xEE000000 - 0xEFFFFFFF (128MB)
*/
#define PKUNITY_APB_BASE io_p2v(0xEE000000)
#define PKUNITY_UART0_BASE (PKUNITY_APB_BASE + 0x000000) /* APB-0 */
#define PKUNITY_UART1_BASE (PKUNITY_APB_BASE + 0x100000) /* APB-1 */
#include "regs-uart.h"
#define PKUNITY_I2C_BASE (PKUNITY_APB_BASE + 0x200000) /* APB-2 */
#include "regs-i2c.h"
#define PKUNITY_SPI_BASE (PKUNITY_APB_BASE + 0x300000) /* APB-3 */
#include "regs-spi.h"
#define PKUNITY_AC97_BASE (PKUNITY_APB_BASE + 0x400000) /* APB-4 */
#include "regs-ac97.h"
#define PKUNITY_GPIO_BASE (PKUNITY_APB_BASE + 0x500000) /* APB-5 */
#include "regs-gpio.h"
#define PKUNITY_INTC_BASE (PKUNITY_APB_BASE + 0x600000) /* APB-6 */
#include "regs-intc.h"
#define PKUNITY_RTC_BASE (PKUNITY_APB_BASE + 0x700000) /* APB-7 */
#include "regs-rtc.h"
#define PKUNITY_OST_BASE (PKUNITY_APB_BASE + 0x800000) /* APB-8 */
#include "regs-ost.h"
#define PKUNITY_RESETC_BASE (PKUNITY_APB_BASE + 0x900000) /* APB-9 */
#include "regs-resetc.h"
#define PKUNITY_PM_BASE (PKUNITY_APB_BASE + 0xA00000) /* APB-10 */
#include "regs-pm.h"
#define PKUNITY_PS2_BASE (PKUNITY_APB_BASE + 0xB00000) /* APB-11 */
#include "regs-ps2.h"
#define PKUNITY_SDC_BASE (PKUNITY_APB_BASE + 0xC00000) /* APB-12 */
#include "regs-sdc.h"

View File

@ -0,0 +1,24 @@
/*
* linux/arch/unicore32/include/mach/bitfield.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __MACH_PUV3_BITFIELD_H__
#define __MACH_PUV3_BITFIELD_H__
#ifndef __ASSEMBLY__
#define UData(Data) ((unsigned long) (Data))
#else
#define UData(Data) (Data)
#endif
#define FIELD(val, vmask, vshift) (((val) & ((UData(1) << (vmask)) - 1)) << (vshift))
#define FMASK(vmask, vshift) (((UData(1) << (vmask)) - 1) << (vshift))
#endif /* __MACH_PUV3_BITFIELD_H__ */

View File

@ -0,0 +1,48 @@
/*
* linux/arch/unicore32/include/mach/dma.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __MACH_PUV3_DMA_H__
#define __MACH_PUV3_DMA_H__
/*
* The PKUnity has six internal DMA channels.
*/
#define MAX_DMA_CHANNELS 6
typedef enum {
DMA_PRIO_HIGH = 0,
DMA_PRIO_MEDIUM = 1,
DMA_PRIO_LOW = 2
} puv3_dma_prio;
/*
* DMA registration
*/
extern int puv3_request_dma(char *name,
puv3_dma_prio prio,
void (*irq_handler)(int, void *),
void (*err_handler)(int, void *),
void *data);
extern void puv3_free_dma(int dma_ch);
static inline void puv3_stop_dma(int ch)
{
writel(readl(DMAC_CONFIG(ch)) & ~DMAC_CONFIG_EN, DMAC_CONFIG(ch));
}
static inline void puv3_resume_dma(int ch)
{
writel(readl(DMAC_CONFIG(ch)) | DMAC_CONFIG_EN, DMAC_CONFIG(ch));
}
#endif /* __MACH_PUV3_DMA_H__ */

View File

@ -0,0 +1,38 @@
/*
* linux/arch/unicore32/include/mach/hardware.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* This file contains the hardware definitions for PKUnity architecture
*/
#ifndef __MACH_PUV3_HARDWARE_H__
#define __MACH_PUV3_HARDWARE_H__
#include "PKUnity.h"
#ifndef __ASSEMBLY__
#define io_p2v(x) (void __iomem *)((x) - PKUNITY_MMIO_BASE)
#define io_v2p(x) (phys_addr_t)((x) + PKUNITY_MMIO_BASE)
#else
#define io_p2v(x) ((x) - PKUNITY_MMIO_BASE)
#define io_v2p(x) ((x) + PKUNITY_MMIO_BASE)
#endif
#define PCIBIOS_MIN_IO 0x4000 /* should lower than 64KB */
#define PCIBIOS_MIN_MEM io_v2p(PKUNITY_PCIMEM_BASE)
/*
* We override the standard dma-mask routines for bouncing.
*/
#define HAVE_ARCH_PCI_SET_DMA_MASK
#define pcibios_assign_all_busses() 1
#endif /* __MACH_PUV3_HARDWARE_H__ */

View File

@ -0,0 +1,20 @@
/*
* linux/arch/unicore32/include/mach/map.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Page table mapping constructs and function prototypes
*/
#define MT_DEVICE 0
#define MT_DEVICE_CACHED 2
#define MT_KUSER 7
#define MT_HIGH_VECTORS 8
#define MT_MEMORY 9
#define MT_ROM 10

View File

@ -0,0 +1,58 @@
/*
* linux/arch/unicore32/include/mach/memory.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __MACH_PUV3_MEMORY_H__
#define __MACH_PUV3_MEMORY_H__
#include <mach/hardware.h>
/* Physical DRAM offset. */
#define PHYS_OFFSET UL(0x00000000)
/* The base address of exception vectors. */
#define VECTORS_BASE UL(0xffff0000)
/* The base address of kuser area. */
#define KUSER_BASE UL(0x80000000)
#ifdef __ASSEMBLY__
/* The byte offset of the kernel image in RAM from the start of RAM. */
#define KERNEL_IMAGE_START 0x00408000
#endif
#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
void puv3_pci_adjust_zones(unsigned long *size, unsigned long *holes);
#define arch_adjust_zones(size, holes) \
puv3_pci_adjust_zones(size, holes)
#endif
/*
* PCI controller in PKUnity-3 masks highest 5-bit for upstream channel,
* so we must limit the DMA allocation within 128M physical memory for
* supporting PCI devices.
*/
#define PCI_DMA_THRESHOLD (PHYS_OFFSET + SZ_128M - 1)
#define is_pcibus_device(dev) (dev && \
(strncmp(dev->bus->name, "pci", 3) == 0))
#define __virt_to_pcibus(x) (__virt_to_phys((x) + PKUNITY_PCIAHB_BASE))
#define __pcibus_to_virt(x) (__phys_to_virt(x) - PKUNITY_PCIAHB_BASE)
/* kuser area */
#define KUSER_VECPAGE_BASE (KUSER_BASE + UL(0x3fff0000))
#define KUSER_UNIGFX_BASE (PAGE_OFFSET + PKUNITY_UNIGFX_MMAP_BASE)
/* kuser_vecpage (0xbfff0000) is ro, and vectors page (0xffff0000) is rw */
#define kuser_vecpage_to_vectors(x) ((x) - (KUSER_VECPAGE_BASE) \
+ (VECTORS_BASE))
#endif

View File

@ -0,0 +1,36 @@
/*
* linux/arch/unicore32/include/mach/ocd.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __MACH_PUV3_OCD_H__
#define __MACH_PUV3_OCD_H__
#if defined(CONFIG_DEBUG_OCD)
static inline void ocd_putc(unsigned int c)
{
int status, i = 0x2000000;
do {
if (--i < 0)
return;
asm volatile ("movc %0, p1.c0, #0" : "=r" (status));
} while (status & 2);
asm("movc p1.c1, %0, #1" : : "r" (c));
}
#define putc(ch) ocd_putc(ch)
#else
#define putc(ch)
#endif
#endif

View File

@ -0,0 +1,43 @@
/*
* linux/arch/unicore/include/mach/pm.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __PUV3_PM_H__
#define __PUV3_PM_H__
#include <linux/suspend.h>
struct puv3_cpu_pm_fns {
int save_count;
void (*save)(unsigned long *);
void (*restore)(unsigned long *);
int (*valid)(suspend_state_t state);
void (*enter)(suspend_state_t state);
int (*prepare)(void);
void (*finish)(void);
};
extern struct puv3_cpu_pm_fns *puv3_cpu_pm_fns;
/* sleep.S */
extern void puv3_cpu_suspend(unsigned int);
extern void puv3_cpu_resume(void);
extern int puv3_pm_enter(suspend_state_t state);
/* Defined in hibernate_asm.S */
extern int restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist);
/* References to section boundaries */
extern const void __nosave_begin, __nosave_end;
extern struct pbe *restore_pblist;
#endif

View File

@ -0,0 +1,32 @@
/*
* PKUnity AC97 Registers
*/
#define PKUNITY_AC97_CONR (PKUNITY_AC97_BASE + 0x0000)
#define PKUNITY_AC97_OCR (PKUNITY_AC97_BASE + 0x0004)
#define PKUNITY_AC97_ICR (PKUNITY_AC97_BASE + 0x0008)
#define PKUNITY_AC97_CRAC (PKUNITY_AC97_BASE + 0x000C)
#define PKUNITY_AC97_INTR (PKUNITY_AC97_BASE + 0x0010)
#define PKUNITY_AC97_INTRSTAT (PKUNITY_AC97_BASE + 0x0014)
#define PKUNITY_AC97_INTRCLEAR (PKUNITY_AC97_BASE + 0x0018)
#define PKUNITY_AC97_ENABLE (PKUNITY_AC97_BASE + 0x001C)
#define PKUNITY_AC97_OUT_FIFO (PKUNITY_AC97_BASE + 0x0020)
#define PKUNITY_AC97_IN_FIFO (PKUNITY_AC97_BASE + 0x0030)
#define AC97_CODEC_REG(v) FIELD((v), 7, 16)
#define AC97_CODEC_VAL(v) FIELD((v), 16, 0)
#define AC97_CODEC_WRITECOMPLETE FIELD(1, 1, 2)
/*
* VAR PLAY SAMPLE RATE
*/
#define AC97_CMD_VPSAMPLE (FIELD(3, 2, 16) | FIELD(3, 2, 0))
/*
* FIX CAPTURE SAMPLE RATE
*/
#define AC97_CMD_FCSAMPLE FIELD(7, 3, 0)
#define AC97_CMD_RESET FIELD(1, 1, 0)
#define AC97_CMD_ENABLE FIELD(1, 1, 0)
#define AC97_CMD_DISABLE FIELD(0, 1, 0)

View File

@ -0,0 +1,81 @@
/*
* PKUnity Direct Memory Access Controller (DMAC)
*/
/*
* Interrupt Status Reg DMAC_ISR.
*/
#define DMAC_ISR (PKUNITY_DMAC_BASE + 0x0020)
/*
* Interrupt Transfer Complete Status Reg DMAC_ITCSR.
*/
#define DMAC_ITCSR (PKUNITY_DMAC_BASE + 0x0050)
/*
* Interrupt Transfer Complete Clear Reg DMAC_ITCCR.
*/
#define DMAC_ITCCR (PKUNITY_DMAC_BASE + 0x0060)
/*
* Interrupt Error Status Reg DMAC_IESR.
*/
#define DMAC_IESR (PKUNITY_DMAC_BASE + 0x0080)
/*
* Interrupt Error Clear Reg DMAC_IECR.
*/
#define DMAC_IECR (PKUNITY_DMAC_BASE + 0x0090)
/*
* Enable Channels Reg DMAC_ENCH.
*/
#define DMAC_ENCH (PKUNITY_DMAC_BASE + 0x00B0)
/*
* DMA control reg. Space [byte]
*/
#define DMASp 0x00000100
/*
* Source Addr DMAC_SRCADDR(ch).
*/
#define DMAC_SRCADDR(ch) (PKUNITY_DMAC_BASE + (ch)*DMASp + 0x00)
/*
* Destination Addr DMAC_DESTADDR(ch).
*/
#define DMAC_DESTADDR(ch) (PKUNITY_DMAC_BASE + (ch)*DMASp + 0x04)
/*
* Control Reg DMAC_CONTROL(ch).
*/
#define DMAC_CONTROL(ch) (PKUNITY_DMAC_BASE + (ch)*DMASp + 0x0C)
/*
* Configuration Reg DMAC_CONFIG(ch).
*/
#define DMAC_CONFIG(ch) (PKUNITY_DMAC_BASE + (ch)*DMASp + 0x10)
#define DMAC_IR_MASK FMASK(6, 0)
/*
* select channel (ch)
*/
#define DMAC_CHANNEL(ch) FIELD(1, 1, (ch))
#define DMAC_CONTROL_SIZE_BYTE(v) (FIELD((v), 12, 14) | \
FIELD(0, 3, 9) | FIELD(0, 3, 6))
#define DMAC_CONTROL_SIZE_HWORD(v) (FIELD((v) >> 1, 12, 14) | \
FIELD(1, 3, 9) | FIELD(1, 3, 6))
#define DMAC_CONTROL_SIZE_WORD(v) (FIELD((v) >> 2, 12, 14) | \
FIELD(2, 3, 9) | FIELD(2, 3, 6))
#define DMAC_CONTROL_DI FIELD(1, 1, 13)
#define DMAC_CONTROL_SI FIELD(1, 1, 12)
#define DMAC_CONTROL_BURST_1BYTE (FIELD(0, 3, 3) | FIELD(0, 3, 0))
#define DMAC_CONTROL_BURST_4BYTE (FIELD(3, 3, 3) | FIELD(3, 3, 0))
#define DMAC_CONTROL_BURST_8BYTE (FIELD(5, 3, 3) | FIELD(5, 3, 0))
#define DMAC_CONTROL_BURST_16BYTE (FIELD(7, 3, 3) | FIELD(7, 3, 0))
#define DMAC_CONFIG_UART0_WR (FIELD(2, 4, 11) | FIELD(1, 2, 1))
#define DMAC_CONFIG_UART0_RD (FIELD(2, 4, 7) | FIELD(2, 2, 1))
#define DMAC_CONFIG_UART1_WR (FIELD(3, 4, 11) | FIELD(1, 2, 1))
#define DMAC_CONFIG_UART1RD (FIELD(3, 4, 7) | FIELD(2, 2, 1))
#define DMAC_CONFIG_AC97WR (FIELD(4, 4, 11) | FIELD(1, 2, 1))
#define DMAC_CONFIG_AC97RD (FIELD(4, 4, 7) | FIELD(2, 2, 1))
#define DMAC_CONFIG_MMCWR (FIELD(7, 4, 11) | FIELD(1, 2, 1))
#define DMAC_CONFIG_MMCRD (FIELD(7, 4, 7) | FIELD(2, 2, 1))
#define DMAC_CONFIG_MASKITC FIELD(1, 1, 4)
#define DMAC_CONFIG_MASKIE FIELD(1, 1, 3)
#define DMAC_CONFIG_EN FIELD(1, 1, 0)

View File

@ -0,0 +1,70 @@
/*
* PKUnity General-Purpose Input/Output (GPIO) Registers
*/
/*
* Voltage Status Reg GPIO_GPLR.
*/
#define GPIO_GPLR (PKUNITY_GPIO_BASE + 0x0000)
/*
* Pin Direction Reg GPIO_GPDR.
*/
#define GPIO_GPDR (PKUNITY_GPIO_BASE + 0x0004)
/*
* Output Pin Set Reg GPIO_GPSR.
*/
#define GPIO_GPSR (PKUNITY_GPIO_BASE + 0x0008)
/*
* Output Pin Clear Reg GPIO_GPCR.
*/
#define GPIO_GPCR (PKUNITY_GPIO_BASE + 0x000C)
/*
* Raise Edge Detect Reg GPIO_GRER.
*/
#define GPIO_GRER (PKUNITY_GPIO_BASE + 0x0010)
/*
* Fall Edge Detect Reg GPIO_GFER.
*/
#define GPIO_GFER (PKUNITY_GPIO_BASE + 0x0014)
/*
* Edge Status Reg GPIO_GEDR.
*/
#define GPIO_GEDR (PKUNITY_GPIO_BASE + 0x0018)
/*
* Sepcial Voltage Detect Reg GPIO_GPIR.
*/
#define GPIO_GPIR (PKUNITY_GPIO_BASE + 0x0020)
#define GPIO_MIN (0)
#define GPIO_MAX (27)
#define GPIO_GPIO(Nb) (0x00000001 << (Nb)) /* GPIO [0..27] */
#define GPIO_GPIO0 GPIO_GPIO(0) /* GPIO [0] */
#define GPIO_GPIO1 GPIO_GPIO(1) /* GPIO [1] */
#define GPIO_GPIO2 GPIO_GPIO(2) /* GPIO [2] */
#define GPIO_GPIO3 GPIO_GPIO(3) /* GPIO [3] */
#define GPIO_GPIO4 GPIO_GPIO(4) /* GPIO [4] */
#define GPIO_GPIO5 GPIO_GPIO(5) /* GPIO [5] */
#define GPIO_GPIO6 GPIO_GPIO(6) /* GPIO [6] */
#define GPIO_GPIO7 GPIO_GPIO(7) /* GPIO [7] */
#define GPIO_GPIO8 GPIO_GPIO(8) /* GPIO [8] */
#define GPIO_GPIO9 GPIO_GPIO(9) /* GPIO [9] */
#define GPIO_GPIO10 GPIO_GPIO(10) /* GPIO [10] */
#define GPIO_GPIO11 GPIO_GPIO(11) /* GPIO [11] */
#define GPIO_GPIO12 GPIO_GPIO(12) /* GPIO [12] */
#define GPIO_GPIO13 GPIO_GPIO(13) /* GPIO [13] */
#define GPIO_GPIO14 GPIO_GPIO(14) /* GPIO [14] */
#define GPIO_GPIO15 GPIO_GPIO(15) /* GPIO [15] */
#define GPIO_GPIO16 GPIO_GPIO(16) /* GPIO [16] */
#define GPIO_GPIO17 GPIO_GPIO(17) /* GPIO [17] */
#define GPIO_GPIO18 GPIO_GPIO(18) /* GPIO [18] */
#define GPIO_GPIO19 GPIO_GPIO(19) /* GPIO [19] */
#define GPIO_GPIO20 GPIO_GPIO(20) /* GPIO [20] */
#define GPIO_GPIO21 GPIO_GPIO(21) /* GPIO [21] */
#define GPIO_GPIO22 GPIO_GPIO(22) /* GPIO [22] */
#define GPIO_GPIO23 GPIO_GPIO(23) /* GPIO [23] */
#define GPIO_GPIO24 GPIO_GPIO(24) /* GPIO [24] */
#define GPIO_GPIO25 GPIO_GPIO(25) /* GPIO [25] */
#define GPIO_GPIO26 GPIO_GPIO(26) /* GPIO [26] */
#define GPIO_GPIO27 GPIO_GPIO(27) /* GPIO [27] */

View File

@ -0,0 +1,63 @@
/*
* PKUnity Inter-integrated Circuit (I2C) Registers
*/
/*
* Control Reg I2C_CON.
*/
#define I2C_CON (PKUNITY_I2C_BASE + 0x0000)
/*
* Target Address Reg I2C_TAR.
*/
#define I2C_TAR (PKUNITY_I2C_BASE + 0x0004)
/*
* Data buffer and command Reg I2C_DATACMD.
*/
#define I2C_DATACMD (PKUNITY_I2C_BASE + 0x0010)
/*
* Enable Reg I2C_ENABLE.
*/
#define I2C_ENABLE (PKUNITY_I2C_BASE + 0x006C)
/*
* Status Reg I2C_STATUS.
*/
#define I2C_STATUS (PKUNITY_I2C_BASE + 0x0070)
/*
* Tx FIFO Length Reg I2C_TXFLR.
*/
#define I2C_TXFLR (PKUNITY_I2C_BASE + 0x0074)
/*
* Rx FIFO Length Reg I2C_RXFLR.
*/
#define I2C_RXFLR (PKUNITY_I2C_BASE + 0x0078)
/*
* Enable Status Reg I2C_ENSTATUS.
*/
#define I2C_ENSTATUS (PKUNITY_I2C_BASE + 0x009C)
#define I2C_CON_MASTER FIELD(1, 1, 0)
#define I2C_CON_SPEED_STD FIELD(1, 2, 1)
#define I2C_CON_SPEED_FAST FIELD(2, 2, 1)
#define I2C_CON_RESTART FIELD(1, 1, 5)
#define I2C_CON_SLAVEDISABLE FIELD(1, 1, 6)
#define I2C_DATACMD_READ FIELD(1, 1, 8)
#define I2C_DATACMD_WRITE FIELD(0, 1, 8)
#define I2C_DATACMD_DAT_MASK FMASK(8, 0)
#define I2C_DATACMD_DAT(v) FIELD((v), 8, 0)
#define I2C_ENABLE_ENABLE FIELD(1, 1, 0)
#define I2C_ENABLE_DISABLE FIELD(0, 1, 0)
#define I2C_STATUS_RFF FIELD(1, 1, 4)
#define I2C_STATUS_RFNE FIELD(1, 1, 3)
#define I2C_STATUS_TFE FIELD(1, 1, 2)
#define I2C_STATUS_TFNF FIELD(1, 1, 1)
#define I2C_STATUS_ACTIVITY FIELD(1, 1, 0)
#define I2C_ENSTATUS_ENABLE FIELD(1, 1, 0)
#define I2C_TAR_THERMAL 0x4f
#define I2C_TAR_SPD 0x50
#define I2C_TAR_PWIC 0x55
#define I2C_TAR_EEPROM 0x57

View File

@ -0,0 +1,28 @@
/*
* PKUNITY Interrupt Controller (INTC) Registers
*/
/*
* INTC Level Reg INTC_ICLR.
*/
#define INTC_ICLR (PKUNITY_INTC_BASE + 0x0000)
/*
* INTC Mask Reg INTC_ICMR.
*/
#define INTC_ICMR (PKUNITY_INTC_BASE + 0x0004)
/*
* INTC Pending Reg INTC_ICPR.
*/
#define INTC_ICPR (PKUNITY_INTC_BASE + 0x0008)
/*
* INTC IRQ Pending Reg INTC_ICIP.
*/
#define INTC_ICIP (PKUNITY_INTC_BASE + 0x000C)
/*
* INTC REAL Pending Reg INTC_ICFP.
*/
#define INTC_ICFP (PKUNITY_INTC_BASE + 0x0010)
/*
* INTC Control Reg INTC_ICCR.
*/
#define INTC_ICCR (PKUNITY_INTC_BASE + 0x0014)

View File

@ -0,0 +1,79 @@
/*
* PKUnity NAND Controller Registers
*/
/*
* ID Reg. 0 NAND_IDR0
*/
#define NAND_IDR0 (PKUNITY_NAND_BASE + 0x0000)
/*
* ID Reg. 1 NAND_IDR1
*/
#define NAND_IDR1 (PKUNITY_NAND_BASE + 0x0004)
/*
* ID Reg. 2 NAND_IDR2
*/
#define NAND_IDR2 (PKUNITY_NAND_BASE + 0x0008)
/*
* ID Reg. 3 NAND_IDR3
*/
#define NAND_IDR3 (PKUNITY_NAND_BASE + 0x000C)
/*
* Page Address Reg 0 NAND_PAR0
*/
#define NAND_PAR0 (PKUNITY_NAND_BASE + 0x0010)
/*
* Page Address Reg 1 NAND_PAR1
*/
#define NAND_PAR1 (PKUNITY_NAND_BASE + 0x0014)
/*
* Page Address Reg 2 NAND_PAR2
*/
#define NAND_PAR2 (PKUNITY_NAND_BASE + 0x0018)
/*
* ECC Enable Reg NAND_ECCEN
*/
#define NAND_ECCEN (PKUNITY_NAND_BASE + 0x001C)
/*
* Buffer Reg NAND_BUF
*/
#define NAND_BUF (PKUNITY_NAND_BASE + 0x0020)
/*
* ECC Status Reg NAND_ECCSR
*/
#define NAND_ECCSR (PKUNITY_NAND_BASE + 0x0024)
/*
* Command Reg NAND_CMD
*/
#define NAND_CMD (PKUNITY_NAND_BASE + 0x0028)
/*
* DMA Configure Reg NAND_DMACR
*/
#define NAND_DMACR (PKUNITY_NAND_BASE + 0x002C)
/*
* Interrupt Reg NAND_IR
*/
#define NAND_IR (PKUNITY_NAND_BASE + 0x0030)
/*
* Interrupt Mask Reg NAND_IMR
*/
#define NAND_IMR (PKUNITY_NAND_BASE + 0x0034)
/*
* Chip Enable Reg NAND_CHIPEN
*/
#define NAND_CHIPEN (PKUNITY_NAND_BASE + 0x0038)
/*
* Address Reg NAND_ADDR
*/
#define NAND_ADDR (PKUNITY_NAND_BASE + 0x003C)
/*
* Command bits NAND_CMD_CMD_MASK
*/
#define NAND_CMD_CMD_MASK FMASK(4, 4)
#define NAND_CMD_CMD_READPAGE FIELD(0x0, 4, 4)
#define NAND_CMD_CMD_ERASEBLOCK FIELD(0x6, 4, 4)
#define NAND_CMD_CMD_READSTATUS FIELD(0x7, 4, 4)
#define NAND_CMD_CMD_WRITEPAGE FIELD(0x8, 4, 4)
#define NAND_CMD_CMD_READID FIELD(0x9, 4, 4)
#define NAND_CMD_CMD_RESET FIELD(0xf, 4, 4)

View File

@ -0,0 +1,92 @@
/*
* PKUnity Operating System Timer (OST) Registers
*/
/*
* Match Reg 0 OST_OSMR0
*/
#define OST_OSMR0 (PKUNITY_OST_BASE + 0x0000)
/*
* Match Reg 1 OST_OSMR1
*/
#define OST_OSMR1 (PKUNITY_OST_BASE + 0x0004)
/*
* Match Reg 2 OST_OSMR2
*/
#define OST_OSMR2 (PKUNITY_OST_BASE + 0x0008)
/*
* Match Reg 3 OST_OSMR3
*/
#define OST_OSMR3 (PKUNITY_OST_BASE + 0x000C)
/*
* Counter Reg OST_OSCR
*/
#define OST_OSCR (PKUNITY_OST_BASE + 0x0010)
/*
* Status Reg OST_OSSR
*/
#define OST_OSSR (PKUNITY_OST_BASE + 0x0014)
/*
* Watchdog Enable Reg OST_OWER
*/
#define OST_OWER (PKUNITY_OST_BASE + 0x0018)
/*
* Interrupt Enable Reg OST_OIER
*/
#define OST_OIER (PKUNITY_OST_BASE + 0x001C)
/*
* PWM Pulse Width Control Reg OST_PWMPWCR
*/
#define OST_PWMPWCR (PKUNITY_OST_BASE + 0x0080)
/*
* PWM Duty Cycle Control Reg OST_PWMDCCR
*/
#define OST_PWMDCCR (PKUNITY_OST_BASE + 0x0084)
/*
* PWM Period Control Reg OST_PWMPCR
*/
#define OST_PWMPCR (PKUNITY_OST_BASE + 0x0088)
/*
* Match detected 0 OST_OSSR_M0
*/
#define OST_OSSR_M0 FIELD(1, 1, 0)
/*
* Match detected 1 OST_OSSR_M1
*/
#define OST_OSSR_M1 FIELD(1, 1, 1)
/*
* Match detected 2 OST_OSSR_M2
*/
#define OST_OSSR_M2 FIELD(1, 1, 2)
/*
* Match detected 3 OST_OSSR_M3
*/
#define OST_OSSR_M3 FIELD(1, 1, 3)
/*
* Interrupt enable 0 OST_OIER_E0
*/
#define OST_OIER_E0 FIELD(1, 1, 0)
/*
* Interrupt enable 1 OST_OIER_E1
*/
#define OST_OIER_E1 FIELD(1, 1, 1)
/*
* Interrupt enable 2 OST_OIER_E2
*/
#define OST_OIER_E2 FIELD(1, 1, 2)
/*
* Interrupt enable 3 OST_OIER_E3
*/
#define OST_OIER_E3 FIELD(1, 1, 3)
/*
* Watchdog Match Enable OST_OWER_WME
*/
#define OST_OWER_WME FIELD(1, 1, 0)
/*
* PWM Full Duty Cycle OST_PWMDCCR_FDCYCLE
*/
#define OST_PWMDCCR_FDCYCLE FIELD(1, 1, 10)

View File

@ -0,0 +1,94 @@
/*
* PKUnity AHB-PCI Bridge Registers
*/
/*
* AHB/PCI fixed physical address for pci addess configuration
*/
/*
* PCICFG Bridge Base Reg.
*/
#define PCICFG_BRIBASE (PKUNITY_PCICFG_BASE + 0x0000)
/*
* PCICFG Address Reg.
*/
#define PCICFG_ADDR (PKUNITY_PCICFG_BASE + 0x0004)
/*
* PCICFG Address Reg.
*/
#define PCICFG_DATA (PKUNITY_PCICFG_BASE + 0x0008)
/*
* PCI Bridge configuration space
*/
#define PCIBRI_ID (PKUNITY_PCIBRI_BASE + 0x0000)
#define PCIBRI_CMD (PKUNITY_PCIBRI_BASE + 0x0004)
#define PCIBRI_CLASS (PKUNITY_PCIBRI_BASE + 0x0008)
#define PCIBRI_LTR (PKUNITY_PCIBRI_BASE + 0x000C)
#define PCIBRI_BAR0 (PKUNITY_PCIBRI_BASE + 0x0010)
#define PCIBRI_BAR1 (PKUNITY_PCIBRI_BASE + 0x0014)
#define PCIBRI_BAR2 (PKUNITY_PCIBRI_BASE + 0x0018)
#define PCIBRI_BAR3 (PKUNITY_PCIBRI_BASE + 0x001C)
#define PCIBRI_BAR4 (PKUNITY_PCIBRI_BASE + 0x0020)
#define PCIBRI_BAR5 (PKUNITY_PCIBRI_BASE + 0x0024)
#define PCIBRI_PCICTL0 (PKUNITY_PCIBRI_BASE + 0x0100)
#define PCIBRI_PCIBAR0 (PKUNITY_PCIBRI_BASE + 0x0104)
#define PCIBRI_PCIAMR0 (PKUNITY_PCIBRI_BASE + 0x0108)
#define PCIBRI_PCITAR0 (PKUNITY_PCIBRI_BASE + 0x010C)
#define PCIBRI_PCICTL1 (PKUNITY_PCIBRI_BASE + 0x0110)
#define PCIBRI_PCIBAR1 (PKUNITY_PCIBRI_BASE + 0x0114)
#define PCIBRI_PCIAMR1 (PKUNITY_PCIBRI_BASE + 0x0118)
#define PCIBRI_PCITAR1 (PKUNITY_PCIBRI_BASE + 0x011C)
#define PCIBRI_PCICTL2 (PKUNITY_PCIBRI_BASE + 0x0120)
#define PCIBRI_PCIBAR2 (PKUNITY_PCIBRI_BASE + 0x0124)
#define PCIBRI_PCIAMR2 (PKUNITY_PCIBRI_BASE + 0x0128)
#define PCIBRI_PCITAR2 (PKUNITY_PCIBRI_BASE + 0x012C)
#define PCIBRI_PCICTL3 (PKUNITY_PCIBRI_BASE + 0x0130)
#define PCIBRI_PCIBAR3 (PKUNITY_PCIBRI_BASE + 0x0134)
#define PCIBRI_PCIAMR3 (PKUNITY_PCIBRI_BASE + 0x0138)
#define PCIBRI_PCITAR3 (PKUNITY_PCIBRI_BASE + 0x013C)
#define PCIBRI_PCICTL4 (PKUNITY_PCIBRI_BASE + 0x0140)
#define PCIBRI_PCIBAR4 (PKUNITY_PCIBRI_BASE + 0x0144)
#define PCIBRI_PCIAMR4 (PKUNITY_PCIBRI_BASE + 0x0148)
#define PCIBRI_PCITAR4 (PKUNITY_PCIBRI_BASE + 0x014C)
#define PCIBRI_PCICTL5 (PKUNITY_PCIBRI_BASE + 0x0150)
#define PCIBRI_PCIBAR5 (PKUNITY_PCIBRI_BASE + 0x0154)
#define PCIBRI_PCIAMR5 (PKUNITY_PCIBRI_BASE + 0x0158)
#define PCIBRI_PCITAR5 (PKUNITY_PCIBRI_BASE + 0x015C)
#define PCIBRI_AHBCTL0 (PKUNITY_PCIBRI_BASE + 0x0180)
#define PCIBRI_AHBBAR0 (PKUNITY_PCIBRI_BASE + 0x0184)
#define PCIBRI_AHBAMR0 (PKUNITY_PCIBRI_BASE + 0x0188)
#define PCIBRI_AHBTAR0 (PKUNITY_PCIBRI_BASE + 0x018C)
#define PCIBRI_AHBCTL1 (PKUNITY_PCIBRI_BASE + 0x0190)
#define PCIBRI_AHBBAR1 (PKUNITY_PCIBRI_BASE + 0x0194)
#define PCIBRI_AHBAMR1 (PKUNITY_PCIBRI_BASE + 0x0198)
#define PCIBRI_AHBTAR1 (PKUNITY_PCIBRI_BASE + 0x019C)
#define PCIBRI_AHBCTL2 (PKUNITY_PCIBRI_BASE + 0x01A0)
#define PCIBRI_AHBBAR2 (PKUNITY_PCIBRI_BASE + 0x01A4)
#define PCIBRI_AHBAMR2 (PKUNITY_PCIBRI_BASE + 0x01A8)
#define PCIBRI_AHBTAR2 (PKUNITY_PCIBRI_BASE + 0x01AC)
#define PCIBRI_AHBCTL3 (PKUNITY_PCIBRI_BASE + 0x01B0)
#define PCIBRI_AHBBAR3 (PKUNITY_PCIBRI_BASE + 0x01B4)
#define PCIBRI_AHBAMR3 (PKUNITY_PCIBRI_BASE + 0x01B8)
#define PCIBRI_AHBTAR3 (PKUNITY_PCIBRI_BASE + 0x01BC)
#define PCIBRI_AHBCTL4 (PKUNITY_PCIBRI_BASE + 0x01C0)
#define PCIBRI_AHBBAR4 (PKUNITY_PCIBRI_BASE + 0x01C4)
#define PCIBRI_AHBAMR4 (PKUNITY_PCIBRI_BASE + 0x01C8)
#define PCIBRI_AHBTAR4 (PKUNITY_PCIBRI_BASE + 0x01CC)
#define PCIBRI_AHBCTL5 (PKUNITY_PCIBRI_BASE + 0x01D0)
#define PCIBRI_AHBBAR5 (PKUNITY_PCIBRI_BASE + 0x01D4)
#define PCIBRI_AHBAMR5 (PKUNITY_PCIBRI_BASE + 0x01D8)
#define PCIBRI_AHBTAR5 (PKUNITY_PCIBRI_BASE + 0x01DC)
#define PCIBRI_CTLx_AT FIELD(1, 1, 2)
#define PCIBRI_CTLx_PREF FIELD(1, 1, 1)
#define PCIBRI_CTLx_MRL FIELD(1, 1, 0)
#define PCIBRI_BARx_ADDR FIELD(0xFFFFFFFC, 30, 2)
#define PCIBRI_BARx_IO FIELD(1, 1, 0)
#define PCIBRI_BARx_MEM FIELD(0, 1, 0)
#define PCIBRI_CMD_IO FIELD(1, 1, 0)
#define PCIBRI_CMD_MEM FIELD(1, 1, 1)

View File

@ -0,0 +1,126 @@
/*
* PKUNITY Power Manager (PM) Registers
*/
/*
* PM Control Reg PM_PMCR
*/
#define PM_PMCR (PKUNITY_PM_BASE + 0x0000)
/*
* PM General Conf. Reg PM_PGCR
*/
#define PM_PGCR (PKUNITY_PM_BASE + 0x0004)
/*
* PM PLL Conf. Reg PM_PPCR
*/
#define PM_PPCR (PKUNITY_PM_BASE + 0x0008)
/*
* PM Wakeup Enable Reg PM_PWER
*/
#define PM_PWER (PKUNITY_PM_BASE + 0x000C)
/*
* PM GPIO Sleep Status Reg PM_PGSR
*/
#define PM_PGSR (PKUNITY_PM_BASE + 0x0010)
/*
* PM Clock Gate Reg PM_PCGR
*/
#define PM_PCGR (PKUNITY_PM_BASE + 0x0014)
/*
* PM SYS PLL Conf. Reg PM_PLLSYSCFG
*/
#define PM_PLLSYSCFG (PKUNITY_PM_BASE + 0x0018)
/*
* PM DDR PLL Conf. Reg PM_PLLDDRCFG
*/
#define PM_PLLDDRCFG (PKUNITY_PM_BASE + 0x001C)
/*
* PM VGA PLL Conf. Reg PM_PLLVGACFG
*/
#define PM_PLLVGACFG (PKUNITY_PM_BASE + 0x0020)
/*
* PM Div Conf. Reg PM_DIVCFG
*/
#define PM_DIVCFG (PKUNITY_PM_BASE + 0x0024)
/*
* PM SYS PLL Status Reg PM_PLLSYSSTATUS
*/
#define PM_PLLSYSSTATUS (PKUNITY_PM_BASE + 0x0028)
/*
* PM DDR PLL Status Reg PM_PLLDDRSTATUS
*/
#define PM_PLLDDRSTATUS (PKUNITY_PM_BASE + 0x002C)
/*
* PM VGA PLL Status Reg PM_PLLVGASTATUS
*/
#define PM_PLLVGASTATUS (PKUNITY_PM_BASE + 0x0030)
/*
* PM Div Status Reg PM_DIVSTATUS
*/
#define PM_DIVSTATUS (PKUNITY_PM_BASE + 0x0034)
/*
* PM Software Reset Reg PM_SWRESET
*/
#define PM_SWRESET (PKUNITY_PM_BASE + 0x0038)
/*
* PM DDR2 PAD Start Reg PM_DDR2START
*/
#define PM_DDR2START (PKUNITY_PM_BASE + 0x003C)
/*
* PM DDR2 PAD Status Reg PM_DDR2CAL0
*/
#define PM_DDR2CAL0 (PKUNITY_PM_BASE + 0x0040)
/*
* PM PLL DFC Done Reg PM_PLLDFCDONE
*/
#define PM_PLLDFCDONE (PKUNITY_PM_BASE + 0x0044)
#define PM_PMCR_SFB FIELD(1, 1, 0)
#define PM_PMCR_IFB FIELD(1, 1, 1)
#define PM_PMCR_CFBSYS FIELD(1, 1, 2)
#define PM_PMCR_CFBDDR FIELD(1, 1, 3)
#define PM_PMCR_CFBVGA FIELD(1, 1, 4)
#define PM_PMCR_CFBDIVBCLK FIELD(1, 1, 5)
/*
* GPIO 8~27 wake-up enable PM_PWER_GPIOHIGH
*/
#define PM_PWER_GPIOHIGH FIELD(1, 1, 8)
/*
* RTC alarm wake-up enable PM_PWER_RTC
*/
#define PM_PWER_RTC FIELD(1, 1, 31)
#define PM_PCGR_BCLK64DDR FIELD(1, 1, 0)
#define PM_PCGR_BCLK64VGA FIELD(1, 1, 1)
#define PM_PCGR_BCLKDDR FIELD(1, 1, 2)
#define PM_PCGR_BCLKPCI FIELD(1, 1, 4)
#define PM_PCGR_BCLKDMAC FIELD(1, 1, 5)
#define PM_PCGR_BCLKUMAL FIELD(1, 1, 6)
#define PM_PCGR_BCLKUSB FIELD(1, 1, 7)
#define PM_PCGR_BCLKMME FIELD(1, 1, 10)
#define PM_PCGR_BCLKNAND FIELD(1, 1, 11)
#define PM_PCGR_BCLKH264E FIELD(1, 1, 12)
#define PM_PCGR_BCLKVGA FIELD(1, 1, 13)
#define PM_PCGR_BCLKH264D FIELD(1, 1, 14)
#define PM_PCGR_VECLK FIELD(1, 1, 15)
#define PM_PCGR_HECLK FIELD(1, 1, 16)
#define PM_PCGR_HDCLK FIELD(1, 1, 17)
#define PM_PCGR_NANDCLK FIELD(1, 1, 18)
#define PM_PCGR_GECLK FIELD(1, 1, 19)
#define PM_PCGR_VGACLK FIELD(1, 1, 20)
#define PM_PCGR_PCICLK FIELD(1, 1, 21)
#define PM_PCGR_SATACLK FIELD(1, 1, 25)
/*
* [23:20]PM_DIVCFG_VGACLK(v)
*/
#define PM_DIVCFG_VGACLK_MASK FMASK(4, 20)
#define PM_DIVCFG_VGACLK(v) FIELD((v), 4, 20)
#define PM_SWRESET_USB FIELD(1, 1, 6)
#define PM_SWRESET_VGADIV FIELD(1, 1, 26)
#define PM_SWRESET_GEDIV FIELD(1, 1, 27)
#define PM_PLLDFCDONE_SYSDFC FIELD(1, 1, 0)
#define PM_PLLDFCDONE_DDRDFC FIELD(1, 1, 1)
#define PM_PLLDFCDONE_VGADFC FIELD(1, 1, 2)

View File

@ -0,0 +1,20 @@
/*
* PKUnity PS2 Controller Registers
*/
/*
* the same as I8042_DATA_REG PS2_DATA
*/
#define PS2_DATA (PKUNITY_PS2_BASE + 0x0060)
/*
* the same as I8042_COMMAND_REG PS2_COMMAND
*/
#define PS2_COMMAND (PKUNITY_PS2_BASE + 0x0064)
/*
* the same as I8042_STATUS_REG PS2_STATUS
*/
#define PS2_STATUS (PKUNITY_PS2_BASE + 0x0064)
/*
* counter reg PS2_CNT
*/
#define PS2_CNT (PKUNITY_PS2_BASE + 0x0068)

View File

@ -0,0 +1,34 @@
/*
* PKUnity Reset Controller (RC) Registers
*/
/*
* Software Reset Register
*/
#define RESETC_SWRR (PKUNITY_RESETC_BASE + 0x0000)
/*
* Reset Status Register
*/
#define RESETC_RSSR (PKUNITY_RESETC_BASE + 0x0004)
/*
* Software Reset Bit
*/
#define RESETC_SWRR_SRB FIELD(1, 1, 0)
/*
* Hardware Reset
*/
#define RESETC_RSSR_HWR FIELD(1, 1, 0)
/*
* Software Reset
*/
#define RESETC_RSSR_SWR FIELD(1, 1, 1)
/*
* Watchdog Reset
*/
#define RESETC_RSSR_WDR FIELD(1, 1, 2)
/*
* Sleep Mode Reset
*/
#define RESETC_RSSR_SMR FIELD(1, 1, 3)

View File

@ -0,0 +1,37 @@
/*
* PKUnity Real-Time Clock (RTC) control registers
*/
/*
* RTC Alarm Reg RTC_RTAR
*/
#define RTC_RTAR (PKUNITY_RTC_BASE + 0x0000)
/*
* RTC Count Reg RTC_RCNR
*/
#define RTC_RCNR (PKUNITY_RTC_BASE + 0x0004)
/*
* RTC Trim Reg RTC_RTTR
*/
#define RTC_RTTR (PKUNITY_RTC_BASE + 0x0008)
/*
* RTC Status Reg RTC_RTSR
*/
#define RTC_RTSR (PKUNITY_RTC_BASE + 0x0010)
/*
* ALarm detected RTC_RTSR_AL
*/
#define RTC_RTSR_AL FIELD(1, 1, 0)
/*
* 1 Hz clock detected RTC_RTSR_HZ
*/
#define RTC_RTSR_HZ FIELD(1, 1, 1)
/*
* ALarm interrupt Enable RTC_RTSR_ALE
*/
#define RTC_RTSR_ALE FIELD(1, 1, 2)
/*
* 1 Hz clock interrupt Enable RTC_RTSR_HZE
*/
#define RTC_RTSR_HZE FIELD(1, 1, 3)

View File

@ -0,0 +1,156 @@
/*
* PKUnity Multi-Media Card and Security Digital Card (MMC/SD) Registers
*/
/*
* Clock Control Reg SDC_CCR
*/
#define SDC_CCR (PKUNITY_SDC_BASE + 0x0000)
/*
* Software Reset Reg SDC_SRR
*/
#define SDC_SRR (PKUNITY_SDC_BASE + 0x0004)
/*
* Argument Reg SDC_ARGUMENT
*/
#define SDC_ARGUMENT (PKUNITY_SDC_BASE + 0x0008)
/*
* Command Reg SDC_COMMAND
*/
#define SDC_COMMAND (PKUNITY_SDC_BASE + 0x000C)
/*
* Block Size Reg SDC_BLOCKSIZE
*/
#define SDC_BLOCKSIZE (PKUNITY_SDC_BASE + 0x0010)
/*
* Block Cound Reg SDC_BLOCKCOUNT
*/
#define SDC_BLOCKCOUNT (PKUNITY_SDC_BASE + 0x0014)
/*
* Transfer Mode Reg SDC_TMR
*/
#define SDC_TMR (PKUNITY_SDC_BASE + 0x0018)
/*
* Response Reg. 0 SDC_RES0
*/
#define SDC_RES0 (PKUNITY_SDC_BASE + 0x001C)
/*
* Response Reg. 1 SDC_RES1
*/
#define SDC_RES1 (PKUNITY_SDC_BASE + 0x0020)
/*
* Response Reg. 2 SDC_RES2
*/
#define SDC_RES2 (PKUNITY_SDC_BASE + 0x0024)
/*
* Response Reg. 3 SDC_RES3
*/
#define SDC_RES3 (PKUNITY_SDC_BASE + 0x0028)
/*
* Read Timeout Control Reg SDC_RTCR
*/
#define SDC_RTCR (PKUNITY_SDC_BASE + 0x002C)
/*
* Interrupt Status Reg SDC_ISR
*/
#define SDC_ISR (PKUNITY_SDC_BASE + 0x0030)
/*
* Interrupt Status Mask Reg SDC_ISMR
*/
#define SDC_ISMR (PKUNITY_SDC_BASE + 0x0034)
/*
* RX FIFO SDC_RXFIFO
*/
#define SDC_RXFIFO (PKUNITY_SDC_BASE + 0x0038)
/*
* TX FIFO SDC_TXFIFO
*/
#define SDC_TXFIFO (PKUNITY_SDC_BASE + 0x003C)
/*
* SD Clock Enable SDC_CCR_CLKEN
*/
#define SDC_CCR_CLKEN FIELD(1, 1, 2)
/*
* [15:8] SDC_CCR_PDIV(v)
*/
#define SDC_CCR_PDIV(v) FIELD((v), 8, 8)
/*
* Software reset enable SDC_SRR_ENABLE
*/
#define SDC_SRR_ENABLE FIELD(0, 1, 0)
/*
* Software reset disable SDC_SRR_DISABLE
*/
#define SDC_SRR_DISABLE FIELD(1, 1, 0)
/*
* Response type SDC_COMMAND_RESTYPE_MASK
*/
#define SDC_COMMAND_RESTYPE_MASK FMASK(2, 0)
/*
* No response SDC_COMMAND_RESTYPE_NONE
*/
#define SDC_COMMAND_RESTYPE_NONE FIELD(0, 2, 0)
/*
* 136-bit long response SDC_COMMAND_RESTYPE_LONG
*/
#define SDC_COMMAND_RESTYPE_LONG FIELD(1, 2, 0)
/*
* 48-bit short response SDC_COMMAND_RESTYPE_SHORT
*/
#define SDC_COMMAND_RESTYPE_SHORT FIELD(2, 2, 0)
/*
* 48-bit short and test if busy response SDC_COMMAND_RESTYPE_SHORTBUSY
*/
#define SDC_COMMAND_RESTYPE_SHORTBUSY FIELD(3, 2, 0)
/*
* data ready SDC_COMMAND_DATAREADY
*/
#define SDC_COMMAND_DATAREADY FIELD(1, 1, 2)
#define SDC_COMMAND_CMDEN FIELD(1, 1, 3)
/*
* [10:5] SDC_COMMAND_CMDINDEX(v)
*/
#define SDC_COMMAND_CMDINDEX(v) FIELD((v), 6, 5)
/*
* [10:0] SDC_BLOCKSIZE_BSMASK(v)
*/
#define SDC_BLOCKSIZE_BSMASK(v) FIELD((v), 11, 0)
/*
* [11:0] SDC_BLOCKCOUNT_BCMASK(v)
*/
#define SDC_BLOCKCOUNT_BCMASK(v) FIELD((v), 12, 0)
/*
* Data Width 1bit SDC_TMR_WTH_1BIT
*/
#define SDC_TMR_WTH_1BIT FIELD(0, 1, 0)
/*
* Data Width 4bit SDC_TMR_WTH_4BIT
*/
#define SDC_TMR_WTH_4BIT FIELD(1, 1, 0)
/*
* Read SDC_TMR_DIR_READ
*/
#define SDC_TMR_DIR_READ FIELD(0, 1, 1)
/*
* Write SDC_TMR_DIR_WRITE
*/
#define SDC_TMR_DIR_WRITE FIELD(1, 1, 1)
#define SDC_IR_MASK FMASK(13, 0)
#define SDC_IR_RESTIMEOUT FIELD(1, 1, 0)
#define SDC_IR_WRITECRC FIELD(1, 1, 1)
#define SDC_IR_READCRC FIELD(1, 1, 2)
#define SDC_IR_TXFIFOREAD FIELD(1, 1, 3)
#define SDC_IR_RXFIFOWRITE FIELD(1, 1, 4)
#define SDC_IR_READTIMEOUT FIELD(1, 1, 5)
#define SDC_IR_DATACOMPLETE FIELD(1, 1, 6)
#define SDC_IR_CMDCOMPLETE FIELD(1, 1, 7)
#define SDC_IR_RXFIFOFULL FIELD(1, 1, 8)
#define SDC_IR_RXFIFOEMPTY FIELD(1, 1, 9)
#define SDC_IR_TXFIFOFULL FIELD(1, 1, 10)
#define SDC_IR_TXFIFOEMPTY FIELD(1, 1, 11)
#define SDC_IR_ENDCMDWITHRES FIELD(1, 1, 12)

View File

@ -0,0 +1,98 @@
/*
* PKUnity Serial Peripheral Interface (SPI) Registers
*/
/*
* Control reg. 0 SPI_CR0
*/
#define SPI_CR0 (PKUNITY_SPI_BASE + 0x0000)
/*
* Control reg. 1 SPI_CR1
*/
#define SPI_CR1 (PKUNITY_SPI_BASE + 0x0004)
/*
* Enable reg SPI_SSIENR
*/
#define SPI_SSIENR (PKUNITY_SPI_BASE + 0x0008)
/*
* Status reg SPI_SR
*/
#define SPI_SR (PKUNITY_SPI_BASE + 0x0028)
/*
* Interrupt Mask reg SPI_IMR
*/
#define SPI_IMR (PKUNITY_SPI_BASE + 0x002C)
/*
* Interrupt Status reg SPI_ISR
*/
#define SPI_ISR (PKUNITY_SPI_BASE + 0x0030)
/*
* Enable SPI Controller SPI_SSIENR_EN
*/
#define SPI_SSIENR_EN FIELD(1, 1, 0)
/*
* SPI Busy SPI_SR_BUSY
*/
#define SPI_SR_BUSY FIELD(1, 1, 0)
/*
* Transmit FIFO Not Full SPI_SR_TFNF
*/
#define SPI_SR_TFNF FIELD(1, 1, 1)
/*
* Transmit FIFO Empty SPI_SR_TFE
*/
#define SPI_SR_TFE FIELD(1, 1, 2)
/*
* Receive FIFO Not Empty SPI_SR_RFNE
*/
#define SPI_SR_RFNE FIELD(1, 1, 3)
/*
* Receive FIFO Full SPI_SR_RFF
*/
#define SPI_SR_RFF FIELD(1, 1, 4)
/*
* Trans. FIFO Empty Interrupt Status SPI_ISR_TXEIS
*/
#define SPI_ISR_TXEIS FIELD(1, 1, 0)
/*
* Trans. FIFO Overflow Interrupt Status SPI_ISR_TXOIS
*/
#define SPI_ISR_TXOIS FIELD(1, 1, 1)
/*
* Receiv. FIFO Underflow Interrupt Status SPI_ISR_RXUIS
*/
#define SPI_ISR_RXUIS FIELD(1, 1, 2)
/*
* Receiv. FIFO Overflow Interrupt Status SPI_ISR_RXOIS
*/
#define SPI_ISR_RXOIS FIELD(1, 1, 3)
/*
* Receiv. FIFO Full Interrupt Status SPI_ISR_RXFIS
*/
#define SPI_ISR_RXFIS FIELD(1, 1, 4)
#define SPI_ISR_MSTIS FIELD(1, 1, 5)
/*
* Trans. FIFO Empty Interrupt Mask SPI_IMR_TXEIM
*/
#define SPI_IMR_TXEIM FIELD(1, 1, 0)
/*
* Trans. FIFO Overflow Interrupt Mask SPI_IMR_TXOIM
*/
#define SPI_IMR_TXOIM FIELD(1, 1, 1)
/*
* Receiv. FIFO Underflow Interrupt Mask SPI_IMR_RXUIM
*/
#define SPI_IMR_RXUIM FIELD(1, 1, 2)
/*
* Receiv. FIFO Overflow Interrupt Mask SPI_IMR_RXOIM
*/
#define SPI_IMR_RXOIM FIELD(1, 1, 3)
/*
* Receiv. FIFO Full Interrupt Mask SPI_IMR_RXFIM
*/
#define SPI_IMR_RXFIM FIELD(1, 1, 4)
#define SPI_IMR_MSTIM FIELD(1, 1, 5)

View File

@ -0,0 +1,3 @@
/*
* PKUnity Universal Asynchronous Receiver/Transmitter (UART) Registers
*/

View File

@ -0,0 +1,229 @@
/*
* PKUnity Ultra Media Access Layer (UMAL) Ethernet MAC Registers
*/
/* MAC module of UMAL */
/* UMAL's MAC module includes G/MII interface, several additional PHY
* interfaces, and MAC control sub-layer, which provides support for control
* frames (e.g. PAUSE frames).
*/
/*
* TX/RX reset and control UMAL_CFG1
*/
#define UMAL_CFG1 (PKUNITY_UMAL_BASE + 0x0000)
/*
* MAC interface mode control UMAL_CFG2
*/
#define UMAL_CFG2 (PKUNITY_UMAL_BASE + 0x0004)
/*
* Inter Packet/Frame Gap UMAL_IPGIFG
*/
#define UMAL_IPGIFG (PKUNITY_UMAL_BASE + 0x0008)
/*
* Collision retry or backoff UMAL_HALFDUPLEX
*/
#define UMAL_HALFDUPLEX (PKUNITY_UMAL_BASE + 0x000c)
/*
* Maximum Frame Length UMAL_MAXFRAME
*/
#define UMAL_MAXFRAME (PKUNITY_UMAL_BASE + 0x0010)
/*
* Test Regsiter UMAL_TESTREG
*/
#define UMAL_TESTREG (PKUNITY_UMAL_BASE + 0x001c)
/*
* MII Management Configure UMAL_MIICFG
*/
#define UMAL_MIICFG (PKUNITY_UMAL_BASE + 0x0020)
/*
* MII Management Command UMAL_MIICMD
*/
#define UMAL_MIICMD (PKUNITY_UMAL_BASE + 0x0024)
/*
* MII Management Address UMAL_MIIADDR
*/
#define UMAL_MIIADDR (PKUNITY_UMAL_BASE + 0x0028)
/*
* MII Management Control UMAL_MIICTRL
*/
#define UMAL_MIICTRL (PKUNITY_UMAL_BASE + 0x002c)
/*
* MII Management Status UMAL_MIISTATUS
*/
#define UMAL_MIISTATUS (PKUNITY_UMAL_BASE + 0x0030)
/*
* MII Managment Indicator UMAL_MIIIDCT
*/
#define UMAL_MIIIDCT (PKUNITY_UMAL_BASE + 0x0034)
/*
* Interface Control UMAL_IFCTRL
*/
#define UMAL_IFCTRL (PKUNITY_UMAL_BASE + 0x0038)
/*
* Interface Status UMAL_IFSTATUS
*/
#define UMAL_IFSTATUS (PKUNITY_UMAL_BASE + 0x003c)
/*
* MAC address (high 4 bytes) UMAL_STADDR1
*/
#define UMAL_STADDR1 (PKUNITY_UMAL_BASE + 0x0040)
/*
* MAC address (low 2 bytes) UMAL_STADDR2
*/
#define UMAL_STADDR2 (PKUNITY_UMAL_BASE + 0x0044)
/* FIFO MODULE OF UMAL */
/* UMAL's FIFO module provides data queuing for increased system level
* throughput
*/
#define UMAL_FIFOCFG0 (PKUNITY_UMAL_BASE + 0x0048)
#define UMAL_FIFOCFG1 (PKUNITY_UMAL_BASE + 0x004c)
#define UMAL_FIFOCFG2 (PKUNITY_UMAL_BASE + 0x0050)
#define UMAL_FIFOCFG3 (PKUNITY_UMAL_BASE + 0x0054)
#define UMAL_FIFOCFG4 (PKUNITY_UMAL_BASE + 0x0058)
#define UMAL_FIFOCFG5 (PKUNITY_UMAL_BASE + 0x005c)
#define UMAL_FIFORAM0 (PKUNITY_UMAL_BASE + 0x0060)
#define UMAL_FIFORAM1 (PKUNITY_UMAL_BASE + 0x0064)
#define UMAL_FIFORAM2 (PKUNITY_UMAL_BASE + 0x0068)
#define UMAL_FIFORAM3 (PKUNITY_UMAL_BASE + 0x006c)
#define UMAL_FIFORAM4 (PKUNITY_UMAL_BASE + 0x0070)
#define UMAL_FIFORAM5 (PKUNITY_UMAL_BASE + 0x0074)
#define UMAL_FIFORAM6 (PKUNITY_UMAL_BASE + 0x0078)
#define UMAL_FIFORAM7 (PKUNITY_UMAL_BASE + 0x007c)
/* MAHBE MODUEL OF UMAL */
/* UMAL's MAHBE module interfaces to the host system through 32-bit AHB Master
* and Slave ports.Registers within the M-AHBE provide Control and Status
* information concerning these transfers.
*/
/*
* Transmit Control UMAL_DMATxCtrl
*/
#define UMAL_DMATxCtrl (PKUNITY_UMAL_BASE + 0x0180)
/*
* Pointer to TX Descripter UMAL_DMATxDescriptor
*/
#define UMAL_DMATxDescriptor (PKUNITY_UMAL_BASE + 0x0184)
/*
* Status of Tx Packet Transfers UMAL_DMATxStatus
*/
#define UMAL_DMATxStatus (PKUNITY_UMAL_BASE + 0x0188)
/*
* Receive Control UMAL_DMARxCtrl
*/
#define UMAL_DMARxCtrl (PKUNITY_UMAL_BASE + 0x018c)
/*
* Pointer to Rx Descriptor UMAL_DMARxDescriptor
*/
#define UMAL_DMARxDescriptor (PKUNITY_UMAL_BASE + 0x0190)
/*
* Status of Rx Packet Transfers UMAL_DMARxStatus
*/
#define UMAL_DMARxStatus (PKUNITY_UMAL_BASE + 0x0194)
/*
* Interrupt Mask UMAL_DMAIntrMask
*/
#define UMAL_DMAIntrMask (PKUNITY_UMAL_BASE + 0x0198)
/*
* Interrupts, read only UMAL_DMAInterrupt
*/
#define UMAL_DMAInterrupt (PKUNITY_UMAL_BASE + 0x019c)
/*
* Commands for UMAL_CFG1 register
*/
#define UMAL_CFG1_TXENABLE FIELD(1, 1, 0)
#define UMAL_CFG1_RXENABLE FIELD(1, 1, 2)
#define UMAL_CFG1_TXFLOWCTL FIELD(1, 1, 4)
#define UMAL_CFG1_RXFLOWCTL FIELD(1, 1, 5)
#define UMAL_CFG1_CONFLPBK FIELD(1, 1, 8)
#define UMAL_CFG1_RESET FIELD(1, 1, 31)
#define UMAL_CFG1_CONFFLCTL (MAC_TX_FLOW_CTL | MAC_RX_FLOW_CTL)
/*
* Commands for UMAL_CFG2 register
*/
#define UMAL_CFG2_FULLDUPLEX FIELD(1, 1, 0)
#define UMAL_CFG2_CRCENABLE FIELD(1, 1, 1)
#define UMAL_CFG2_PADCRC FIELD(1, 1, 2)
#define UMAL_CFG2_LENGTHCHECK FIELD(1, 1, 4)
#define UMAL_CFG2_MODEMASK FMASK(2, 8)
#define UMAL_CFG2_NIBBLEMODE FIELD(1, 2, 8)
#define UMAL_CFG2_BYTEMODE FIELD(2, 2, 8)
#define UMAL_CFG2_PREAMBLENMASK FMASK(4, 12)
#define UMAL_CFG2_DEFPREAMBLEN FIELD(7, 4, 12)
#define UMAL_CFG2_FD100 (UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_NIBBLEMODE \
| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
| UMAL_CFG2_CRCENABLE | UMAL_CFG2_FULLDUPLEX)
#define UMAL_CFG2_FD1000 (UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_BYTEMODE \
| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
| UMAL_CFG2_CRCENABLE | UMAL_CFG2_FULLDUPLEX)
#define UMAL_CFG2_HD100 (UMAL_CFG2_DEFPREAMBLEN | UMAL_CFG2_NIBBLEMODE \
| UMAL_CFG2_LENGTHCHECK | UMAL_CFG2_PADCRC \
| UMAL_CFG2_CRCENABLE)
/*
* Command for UMAL_IFCTRL register
*/
#define UMAL_IFCTRL_RESET FIELD(1, 1, 31)
/*
* Command for UMAL_MIICFG register
*/
#define UMAL_MIICFG_RESET FIELD(1, 1, 31)
/*
* Command for UMAL_MIICMD register
*/
#define UMAL_MIICMD_READ FIELD(1, 1, 0)
/*
* Command for UMAL_MIIIDCT register
*/
#define UMAL_MIIIDCT_BUSY FIELD(1, 1, 0)
#define UMAL_MIIIDCT_NOTVALID FIELD(1, 1, 2)
/*
* Commands for DMATxCtrl regesters
*/
#define UMAL_DMA_Enable FIELD(1, 1, 0)
/*
* Commands for DMARxCtrl regesters
*/
#define UMAL_DMAIntrMask_ENABLEHALFWORD FIELD(1, 1, 16)
/*
* Command for DMARxStatus
*/
#define CLR_RX_BUS_ERR FIELD(1, 1, 3)
#define CLR_RX_OVERFLOW FIELD(1, 1, 2)
#define CLR_RX_PKT FIELD(1, 1, 0)
/*
* Command for DMATxStatus
*/
#define CLR_TX_BUS_ERR FIELD(1, 1, 3)
#define CLR_TX_UNDERRUN FIELD(1, 1, 1)
#define CLR_TX_PKT FIELD(1, 1, 0)
/*
* Commands for DMAIntrMask and DMAInterrupt register
*/
#define INT_RX_MASK FIELD(0xd, 4, 4)
#define INT_TX_MASK FIELD(0xb, 4, 0)
#define INT_RX_BUS_ERR FIELD(1, 1, 7)
#define INT_RX_OVERFLOW FIELD(1, 1, 6)
#define INT_RX_PKT FIELD(1, 1, 4)
#define INT_TX_BUS_ERR FIELD(1, 1, 3)
#define INT_TX_UNDERRUN FIELD(1, 1, 1)
#define INT_TX_PKT FIELD(1, 1, 0)
/*
* MARCOS of UMAL's descriptors
*/
#define UMAL_DESC_PACKETSIZE_EMPTY FIELD(1, 1, 31)
#define UMAL_DESC_PACKETSIZE_NONEMPTY FIELD(0, 1, 31)
#define UMAL_DESC_PACKETSIZE_SIZEMASK FMASK(12, 0)

View File

@ -0,0 +1,200 @@
/*
* PKUnity UNIGFX Registers
*/
#define UDE_BASE (PKUNITY_UNIGFX_BASE + 0x1400)
#define UGE_BASE (PKUNITY_UNIGFX_BASE + 0x0000)
/*
* command reg for UNIGFX DE
*/
/*
* control reg UDE_CFG
*/
#define UDE_CFG (UDE_BASE + 0x0000)
/*
* framebuffer start address reg UDE_FSA
*/
#define UDE_FSA (UDE_BASE + 0x0004)
/*
* line size reg UDE_LS
*/
#define UDE_LS (UDE_BASE + 0x0008)
/*
* pitch size reg UDE_PS
*/
#define UDE_PS (UDE_BASE + 0x000C)
/*
* horizontal active time reg UDE_HAT
*/
#define UDE_HAT (UDE_BASE + 0x0010)
/*
* horizontal blank time reg UDE_HBT
*/
#define UDE_HBT (UDE_BASE + 0x0014)
/*
* horizontal sync time reg UDE_HST
*/
#define UDE_HST (UDE_BASE + 0x0018)
/*
* vertival active time reg UDE_VAT
*/
#define UDE_VAT (UDE_BASE + 0x001C)
/*
* vertival blank time reg UDE_VBT
*/
#define UDE_VBT (UDE_BASE + 0x0020)
/*
* vertival sync time reg UDE_VST
*/
#define UDE_VST (UDE_BASE + 0x0024)
/*
* cursor position UDE_CXY
*/
#define UDE_CXY (UDE_BASE + 0x0028)
/*
* cursor front color UDE_CC0
*/
#define UDE_CC0 (UDE_BASE + 0x002C)
/*
* cursor background color UDE_CC1
*/
#define UDE_CC1 (UDE_BASE + 0x0030)
/*
* video position UDE_VXY
*/
#define UDE_VXY (UDE_BASE + 0x0034)
/*
* video start address reg UDE_VSA
*/
#define UDE_VSA (UDE_BASE + 0x0040)
/*
* video size reg UDE_VS
*/
#define UDE_VS (UDE_BASE + 0x004C)
/*
* command reg for UNIGFX GE
*/
/*
* src xy reg UGE_SRCXY
*/
#define UGE_SRCXY (UGE_BASE + 0x0000)
/*
* dst xy reg UGE_DSTXY
*/
#define UGE_DSTXY (UGE_BASE + 0x0004)
/*
* pitch reg UGE_PITCH
*/
#define UGE_PITCH (UGE_BASE + 0x0008)
/*
* src start reg UGE_SRCSTART
*/
#define UGE_SRCSTART (UGE_BASE + 0x000C)
/*
* dst start reg UGE_DSTSTART
*/
#define UGE_DSTSTART (UGE_BASE + 0x0010)
/*
* width height reg UGE_WIDHEIGHT
*/
#define UGE_WIDHEIGHT (UGE_BASE + 0x0014)
/*
* rop alpah reg UGE_ROPALPHA
*/
#define UGE_ROPALPHA (UGE_BASE + 0x0018)
/*
* front color UGE_FCOLOR
*/
#define UGE_FCOLOR (UGE_BASE + 0x001C)
/*
* background color UGE_BCOLOR
*/
#define UGE_BCOLOR (UGE_BASE + 0x0020)
/*
* src color key for high value UGE_SCH
*/
#define UGE_SCH (UGE_BASE + 0x0024)
/*
* dst color key for high value UGE_DCH
*/
#define UGE_DCH (UGE_BASE + 0x0028)
/*
* src color key for low value UGE_SCL
*/
#define UGE_SCL (UGE_BASE + 0x002C)
/*
* dst color key for low value UGE_DCL
*/
#define UGE_DCL (UGE_BASE + 0x0030)
/*
* clip 0 reg UGE_CLIP0
*/
#define UGE_CLIP0 (UGE_BASE + 0x0034)
/*
* clip 1 reg UGE_CLIP1
*/
#define UGE_CLIP1 (UGE_BASE + 0x0038)
/*
* command reg UGE_COMMAND
*/
#define UGE_COMMAND (UGE_BASE + 0x003C)
/*
* pattern 0 UGE_P0
*/
#define UGE_P0 (UGE_BASE + 0x0040)
#define UGE_P1 (UGE_BASE + 0x0044)
#define UGE_P2 (UGE_BASE + 0x0048)
#define UGE_P3 (UGE_BASE + 0x004C)
#define UGE_P4 (UGE_BASE + 0x0050)
#define UGE_P5 (UGE_BASE + 0x0054)
#define UGE_P6 (UGE_BASE + 0x0058)
#define UGE_P7 (UGE_BASE + 0x005C)
#define UGE_P8 (UGE_BASE + 0x0060)
#define UGE_P9 (UGE_BASE + 0x0064)
#define UGE_P10 (UGE_BASE + 0x0068)
#define UGE_P11 (UGE_BASE + 0x006C)
#define UGE_P12 (UGE_BASE + 0x0070)
#define UGE_P13 (UGE_BASE + 0x0074)
#define UGE_P14 (UGE_BASE + 0x0078)
#define UGE_P15 (UGE_BASE + 0x007C)
#define UGE_P16 (UGE_BASE + 0x0080)
#define UGE_P17 (UGE_BASE + 0x0084)
#define UGE_P18 (UGE_BASE + 0x0088)
#define UGE_P19 (UGE_BASE + 0x008C)
#define UGE_P20 (UGE_BASE + 0x0090)
#define UGE_P21 (UGE_BASE + 0x0094)
#define UGE_P22 (UGE_BASE + 0x0098)
#define UGE_P23 (UGE_BASE + 0x009C)
#define UGE_P24 (UGE_BASE + 0x00A0)
#define UGE_P25 (UGE_BASE + 0x00A4)
#define UGE_P26 (UGE_BASE + 0x00A8)
#define UGE_P27 (UGE_BASE + 0x00AC)
#define UGE_P28 (UGE_BASE + 0x00B0)
#define UGE_P29 (UGE_BASE + 0x00B4)
#define UGE_P30 (UGE_BASE + 0x00B8)
#define UGE_P31 (UGE_BASE + 0x00BC)
#define UDE_CFG_DST_MASK FMASK(2, 8)
#define UDE_CFG_DST8 FIELD(0x0, 2, 8)
#define UDE_CFG_DST16 FIELD(0x1, 2, 8)
#define UDE_CFG_DST24 FIELD(0x2, 2, 8)
#define UDE_CFG_DST32 FIELD(0x3, 2, 8)
/*
* GDEN enable UDE_CFG_GDEN_ENABLE
*/
#define UDE_CFG_GDEN_ENABLE FIELD(1, 1, 3)
/*
* VDEN enable UDE_CFG_VDEN_ENABLE
*/
#define UDE_CFG_VDEN_ENABLE FIELD(1, 1, 4)
/*
* CDEN enable UDE_CFG_CDEN_ENABLE
*/
#define UDE_CFG_CDEN_ENABLE FIELD(1, 1, 5)
/*
* TIMEUP enable UDE_CFG_TIMEUP_ENABLE
*/
#define UDE_CFG_TIMEUP_ENABLE FIELD(1, 1, 6)

View File

@ -0,0 +1,34 @@
/*
* linux/arch/unicore32/include/mach/uncompress.h
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*/
#ifndef __MACH_PUV3_UNCOMPRESS_H__
#define __MACH_PUV3_UNCOMPRESS_H__
#include "hardware.h"
#include "ocd.h"
extern char input_data[];
extern char input_data_end[];
static void arch_decomp_puts(const char *ptr)
{
char c;
while ((c = *ptr++) != '\0') {
if (c == '\n')
putc('\r');
putc(c);
}
}
#define ARCH_HAVE_DECOMP_PUTS
#endif /* __MACH_PUV3_UNCOMPRESS_H__ */

View File

@ -0,0 +1,33 @@
#
# Makefile for the linux kernel.
#
# Object file lists.
obj-y := dma.o elf.o entry.o process.o ptrace.o
obj-y += setup.o signal.o sys.o stacktrace.o traps.o
obj-$(CONFIG_MODULES) += ksyms.o module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_CPU_FREQ) += cpu-ucv2.o
obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o
# obj-y for architecture PKUnity v3
obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o
obj-$(CONFIG_PUV3_GPIO) += gpio.o
obj-$(CONFIG_PUV3_RTC) += rtc.o
obj-$(CONFIG_PUV3_PWM) += pwm.o
obj-$(CONFIG_PUV3_PM) += pm.o sleep.o
obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
obj-$(CONFIG_PCI) += pci.o
# obj-y for specific machines
obj-$(CONFIG_ARCH_PUV3) += puv3-core.o
obj-$(CONFIG_PUV3_NB0916) += puv3-nb0916.o
head-y := head.o
obj-$(CONFIG_DEBUG_LL) += debug.o
extra-y := $(head-y) init_task.o vmlinux.lds

View File

@ -0,0 +1,112 @@
/*
* linux/arch/unicore32/kernel/asm-offsets.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* Generate definitions needed by assembly language modules.
* This code generates raw asm output which is post-processed to extract
* and format the required data.
*
* 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/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/kbuild.h>
#include <linux/suspend.h>
#include <linux/thread_info.h>
#include <asm/memory.h>
#include <asm/suspend.h>
/*
* GCC 3.0, 3.1: general bad code generation.
* GCC 3.2.0: incorrect function argument offset calculation.
* GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
* (http://gcc.gnu.org/PR8896) and incorrect structure
* initialisation in fs/jffs2/erase.c
*/
#if (__GNUC__ < 4)
#error Your compiler should upgrade to uc4
#error Known good compilers: 4.2.2
#endif
int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
#ifdef CONFIG_UNICORE_FPU_F64
DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
#endif
BLANK();
DEFINE(S_R0, offsetof(struct pt_regs, UCreg_00));
DEFINE(S_R1, offsetof(struct pt_regs, UCreg_01));
DEFINE(S_R2, offsetof(struct pt_regs, UCreg_02));
DEFINE(S_R3, offsetof(struct pt_regs, UCreg_03));
DEFINE(S_R4, offsetof(struct pt_regs, UCreg_04));
DEFINE(S_R5, offsetof(struct pt_regs, UCreg_05));
DEFINE(S_R6, offsetof(struct pt_regs, UCreg_06));
DEFINE(S_R7, offsetof(struct pt_regs, UCreg_07));
DEFINE(S_R8, offsetof(struct pt_regs, UCreg_08));
DEFINE(S_R9, offsetof(struct pt_regs, UCreg_09));
DEFINE(S_R10, offsetof(struct pt_regs, UCreg_10));
DEFINE(S_R11, offsetof(struct pt_regs, UCreg_11));
DEFINE(S_R12, offsetof(struct pt_regs, UCreg_12));
DEFINE(S_R13, offsetof(struct pt_regs, UCreg_13));
DEFINE(S_R14, offsetof(struct pt_regs, UCreg_14));
DEFINE(S_R15, offsetof(struct pt_regs, UCreg_15));
DEFINE(S_R16, offsetof(struct pt_regs, UCreg_16));
DEFINE(S_R17, offsetof(struct pt_regs, UCreg_17));
DEFINE(S_R18, offsetof(struct pt_regs, UCreg_18));
DEFINE(S_R19, offsetof(struct pt_regs, UCreg_19));
DEFINE(S_R20, offsetof(struct pt_regs, UCreg_20));
DEFINE(S_R21, offsetof(struct pt_regs, UCreg_21));
DEFINE(S_R22, offsetof(struct pt_regs, UCreg_22));
DEFINE(S_R23, offsetof(struct pt_regs, UCreg_23));
DEFINE(S_R24, offsetof(struct pt_regs, UCreg_24));
DEFINE(S_R25, offsetof(struct pt_regs, UCreg_25));
DEFINE(S_R26, offsetof(struct pt_regs, UCreg_26));
DEFINE(S_FP, offsetof(struct pt_regs, UCreg_fp));
DEFINE(S_IP, offsetof(struct pt_regs, UCreg_ip));
DEFINE(S_SP, offsetof(struct pt_regs, UCreg_sp));
DEFINE(S_LR, offsetof(struct pt_regs, UCreg_lr));
DEFINE(S_PC, offsetof(struct pt_regs, UCreg_pc));
DEFINE(S_PSR, offsetof(struct pt_regs, UCreg_asr));
DEFINE(S_OLD_R0, offsetof(struct pt_regs, UCreg_ORIG_00));
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK();
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
BLANK();
DEFINE(VM_EXEC, VM_EXEC);
BLANK();
DEFINE(PAGE_SZ, PAGE_SIZE);
BLANK();
DEFINE(SYS_ERROR0, 0x9f0000);
BLANK();
DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
DEFINE(PBE_ORIN_ADDRESS, offsetof(struct pbe, orig_address));
DEFINE(PBE_NEXT, offsetof(struct pbe, next));
DEFINE(SWSUSP_CPU, offsetof(struct swsusp_arch_regs, \
cpu_context));
#ifdef CONFIG_UNICORE_FPU_F64
DEFINE(SWSUSP_FPSTATE, offsetof(struct swsusp_arch_regs, \
fpstate));
#endif
BLANK();
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
return 0;
}

View File

@ -0,0 +1,390 @@
/*
* linux/arch/unicore32/kernel/clock.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <mach/hardware.h>
/*
* Very simple clock implementation
*/
struct clk {
struct list_head node;
unsigned long rate;
const char *name;
};
static struct clk clk_ost_clk = {
.name = "OST_CLK",
.rate = CLOCK_TICK_RATE,
};
static struct clk clk_mclk_clk = {
.name = "MAIN_CLK",
};
static struct clk clk_bclk32_clk = {
.name = "BUS32_CLK",
};
static struct clk clk_ddr_clk = {
.name = "DDR_CLK",
};
static struct clk clk_vga_clk = {
.name = "VGA_CLK",
};
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0) {
clk = p;
break;
}
}
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
struct {
unsigned long rate;
unsigned long cfg;
unsigned long div;
} vga_clk_table[] = {
{.rate = 25175000, .cfg = 0x00002001, .div = 0x9},
{.rate = 31500000, .cfg = 0x00002001, .div = 0x7},
{.rate = 40000000, .cfg = 0x00003801, .div = 0x9},
{.rate = 49500000, .cfg = 0x00003801, .div = 0x7},
{.rate = 65000000, .cfg = 0x00002c01, .div = 0x4},
{.rate = 78750000, .cfg = 0x00002400, .div = 0x7},
{.rate = 108000000, .cfg = 0x00002c01, .div = 0x2},
{.rate = 106500000, .cfg = 0x00003c01, .div = 0x3},
{.rate = 50650000, .cfg = 0x00106400, .div = 0x9},
{.rate = 61500000, .cfg = 0x00106400, .div = 0xa},
{.rate = 85500000, .cfg = 0x00002800, .div = 0x6},
};
struct {
unsigned long mrate;
unsigned long prate;
} mclk_clk_table[] = {
{.mrate = 500000000, .prate = 0x00109801},
{.mrate = 525000000, .prate = 0x00104C00},
{.mrate = 550000000, .prate = 0x00105000},
{.mrate = 575000000, .prate = 0x00105400},
{.mrate = 600000000, .prate = 0x00105800},
{.mrate = 625000000, .prate = 0x00105C00},
{.mrate = 650000000, .prate = 0x00106000},
{.mrate = 675000000, .prate = 0x00106400},
{.mrate = 700000000, .prate = 0x00106800},
{.mrate = 725000000, .prate = 0x00106C00},
{.mrate = 750000000, .prate = 0x00107000},
{.mrate = 775000000, .prate = 0x00107400},
{.mrate = 800000000, .prate = 0x00107800},
};
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (clk == &clk_vga_clk) {
unsigned long pll_vgacfg, pll_vgadiv;
int ret, i;
/* lookup vga_clk_table */
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(vga_clk_table); i++) {
if (rate == vga_clk_table[i].rate) {
pll_vgacfg = vga_clk_table[i].cfg;
pll_vgadiv = vga_clk_table[i].div;
ret = 0;
break;
}
}
if (ret)
return ret;
if (readl(PM_PLLVGACFG) == pll_vgacfg)
return 0;
/* set pll vga cfg reg. */
writel(pll_vgacfg, PM_PLLVGACFG);
writel(PM_PMCR_CFBVGA, PM_PMCR);
while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_VGADFC)
!= PM_PLLDFCDONE_VGADFC)
udelay(100); /* about 1ms */
/* set div cfg reg. */
writel(readl(PM_PCGR) | PM_PCGR_VGACLK, PM_PCGR);
writel((readl(PM_DIVCFG) & ~PM_DIVCFG_VGACLK_MASK)
| PM_DIVCFG_VGACLK(pll_vgadiv), PM_DIVCFG);
writel(readl(PM_SWRESET) | PM_SWRESET_VGADIV, PM_SWRESET);
while ((readl(PM_SWRESET) & PM_SWRESET_VGADIV)
== PM_SWRESET_VGADIV)
udelay(100); /* 65536 bclk32, about 320us */
writel(readl(PM_PCGR) & ~PM_PCGR_VGACLK, PM_PCGR);
}
#ifdef CONFIG_CPU_FREQ
if (clk == &clk_mclk_clk) {
u32 pll_rate, divstatus = PM_DIVSTATUS;
int ret, i;
/* lookup mclk_clk_table */
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(mclk_clk_table); i++) {
if (rate == mclk_clk_table[i].mrate) {
pll_rate = mclk_clk_table[i].prate;
clk_mclk_clk.rate = mclk_clk_table[i].mrate;
ret = 0;
break;
}
}
if (ret)
return ret;
if (clk_mclk_clk.rate)
clk_bclk32_clk.rate = clk_mclk_clk.rate
/ (((divstatus & 0x0000f000) >> 12) + 1);
/* set pll sys cfg reg. */
PM_PLLSYSCFG = pll_rate;
PM_PMCR = PM_PMCR_CFBSYS;
while ((PM_PLLDFCDONE & PM_PLLDFCDONE_SYSDFC)
!= PM_PLLDFCDONE_SYSDFC)
udelay(100);
/* about 1ms */
}
#endif
return 0;
}
EXPORT_SYMBOL(clk_set_rate);
int clk_register(struct clk *clk)
{
mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
mutex_unlock(&clocks_mutex);
printk(KERN_DEFAULT "PKUnity PM: %s %lu.%02luM\n", clk->name,
(clk->rate)/1000000, (clk->rate)/10000 % 100);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
mutex_lock(&clocks_mutex);
list_del(&clk->node);
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
struct {
unsigned long prate;
unsigned long rate;
} pllrate_table[] = {
{.prate = 0x00002001, .rate = 250000000},
{.prate = 0x00104801, .rate = 250000000},
{.prate = 0x00104C01, .rate = 262500000},
{.prate = 0x00002401, .rate = 275000000},
{.prate = 0x00105001, .rate = 275000000},
{.prate = 0x00105401, .rate = 287500000},
{.prate = 0x00002801, .rate = 300000000},
{.prate = 0x00105801, .rate = 300000000},
{.prate = 0x00105C01, .rate = 312500000},
{.prate = 0x00002C01, .rate = 325000000},
{.prate = 0x00106001, .rate = 325000000},
{.prate = 0x00106401, .rate = 337500000},
{.prate = 0x00003001, .rate = 350000000},
{.prate = 0x00106801, .rate = 350000000},
{.prate = 0x00106C01, .rate = 362500000},
{.prate = 0x00003401, .rate = 375000000},
{.prate = 0x00107001, .rate = 375000000},
{.prate = 0x00107401, .rate = 387500000},
{.prate = 0x00003801, .rate = 400000000},
{.prate = 0x00107801, .rate = 400000000},
{.prate = 0x00107C01, .rate = 412500000},
{.prate = 0x00003C01, .rate = 425000000},
{.prate = 0x00108001, .rate = 425000000},
{.prate = 0x00108401, .rate = 437500000},
{.prate = 0x00004001, .rate = 450000000},
{.prate = 0x00108801, .rate = 450000000},
{.prate = 0x00108C01, .rate = 462500000},
{.prate = 0x00004401, .rate = 475000000},
{.prate = 0x00109001, .rate = 475000000},
{.prate = 0x00109401, .rate = 487500000},
{.prate = 0x00004801, .rate = 500000000},
{.prate = 0x00109801, .rate = 500000000},
{.prate = 0x00104C00, .rate = 525000000},
{.prate = 0x00002400, .rate = 550000000},
{.prate = 0x00105000, .rate = 550000000},
{.prate = 0x00105400, .rate = 575000000},
{.prate = 0x00002800, .rate = 600000000},
{.prate = 0x00105800, .rate = 600000000},
{.prate = 0x00105C00, .rate = 625000000},
{.prate = 0x00002C00, .rate = 650000000},
{.prate = 0x00106000, .rate = 650000000},
{.prate = 0x00106400, .rate = 675000000},
{.prate = 0x00003000, .rate = 700000000},
{.prate = 0x00106800, .rate = 700000000},
{.prate = 0x00106C00, .rate = 725000000},
{.prate = 0x00003400, .rate = 750000000},
{.prate = 0x00107000, .rate = 750000000},
{.prate = 0x00107400, .rate = 775000000},
{.prate = 0x00003800, .rate = 800000000},
{.prate = 0x00107800, .rate = 800000000},
{.prate = 0x00107C00, .rate = 825000000},
{.prate = 0x00003C00, .rate = 850000000},
{.prate = 0x00108000, .rate = 850000000},
{.prate = 0x00108400, .rate = 875000000},
{.prate = 0x00004000, .rate = 900000000},
{.prate = 0x00108800, .rate = 900000000},
{.prate = 0x00108C00, .rate = 925000000},
{.prate = 0x00004400, .rate = 950000000},
{.prate = 0x00109000, .rate = 950000000},
{.prate = 0x00109400, .rate = 975000000},
{.prate = 0x00004800, .rate = 1000000000},
{.prate = 0x00109800, .rate = 1000000000},
};
struct {
unsigned long prate;
unsigned long drate;
} pddr_table[] = {
{.prate = 0x00100800, .drate = 44236800},
{.prate = 0x00100C00, .drate = 66355200},
{.prate = 0x00101000, .drate = 88473600},
{.prate = 0x00101400, .drate = 110592000},
{.prate = 0x00101800, .drate = 132710400},
{.prate = 0x00101C01, .drate = 154828800},
{.prate = 0x00102001, .drate = 176947200},
{.prate = 0x00102401, .drate = 199065600},
{.prate = 0x00102801, .drate = 221184000},
{.prate = 0x00102C01, .drate = 243302400},
{.prate = 0x00103001, .drate = 265420800},
{.prate = 0x00103401, .drate = 287539200},
{.prate = 0x00103801, .drate = 309657600},
{.prate = 0x00103C01, .drate = 331776000},
{.prate = 0x00104001, .drate = 353894400},
};
static int __init clk_init(void)
{
#ifdef CONFIG_PUV3_PM
u32 pllrate, divstatus = readl(PM_DIVSTATUS);
u32 pcgr_val = readl(PM_PCGR);
int i;
pcgr_val |= PM_PCGR_BCLKMME | PM_PCGR_BCLKH264E | PM_PCGR_BCLKH264D
| PM_PCGR_HECLK | PM_PCGR_HDCLK;
writel(pcgr_val, PM_PCGR);
pllrate = readl(PM_PLLSYSSTATUS);
/* lookup pmclk_table */
clk_mclk_clk.rate = 0;
for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
if (pllrate == pllrate_table[i].prate) {
clk_mclk_clk.rate = pllrate_table[i].rate;
break;
}
}
if (clk_mclk_clk.rate)
clk_bclk32_clk.rate = clk_mclk_clk.rate /
(((divstatus & 0x0000f000) >> 12) + 1);
pllrate = readl(PM_PLLDDRSTATUS);
/* lookup pddr_table */
clk_ddr_clk.rate = 0;
for (i = 0; i < ARRAY_SIZE(pddr_table); i++) {
if (pllrate == pddr_table[i].prate) {
clk_ddr_clk.rate = pddr_table[i].drate;
break;
}
}
pllrate = readl(PM_PLLVGASTATUS);
/* lookup pvga_table */
clk_vga_clk.rate = 0;
for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
if (pllrate == pllrate_table[i].prate) {
clk_vga_clk.rate = pllrate_table[i].rate;
break;
}
}
if (clk_vga_clk.rate)
clk_vga_clk.rate = clk_vga_clk.rate /
(((divstatus & 0x00f00000) >> 20) + 1);
clk_register(&clk_vga_clk);
#endif
#ifdef CONFIG_ARCH_FPGA
clk_ddr_clk.rate = 33000000;
clk_mclk_clk.rate = 33000000;
clk_bclk32_clk.rate = 33000000;
#endif
clk_register(&clk_ddr_clk);
clk_register(&clk_mclk_clk);
clk_register(&clk_bclk32_clk);
clk_register(&clk_ost_clk);
return 0;
}
core_initcall(clk_init);

View File

@ -0,0 +1,93 @@
/*
* linux/arch/unicore32/kernel/cpu-ucv2.c: clock scaling for the UniCore-II
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <mach/hardware.h>
static struct cpufreq_driver ucv2_driver;
/* make sure that only the "userspace" governor is run
* -- anything else wouldn't make sense on this platform, anyway.
*/
int ucv2_verify_speed(struct cpufreq_policy *policy)
{
if (policy->cpu)
return -EINVAL;
cpufreq_verify_within_limits(policy,
policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
return 0;
}
static unsigned int ucv2_getspeed(unsigned int cpu)
{
struct clk *mclk = clk_get(NULL, "MAIN_CLK");
if (cpu)
return 0;
return clk_get_rate(mclk)/1000;
}
static int ucv2_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int cur = ucv2_getspeed(0);
struct cpufreq_freqs freqs;
struct clk *mclk = clk_get(NULL, "MAIN_CLK");
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (!clk_set_rate(mclk, target_freq * 1000)) {
freqs.old = cur;
freqs.new = target_freq;
freqs.cpu = 0;
}
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
}
static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -EINVAL;
policy->cur = ucv2_getspeed(0);
policy->min = policy->cpuinfo.min_freq = 250000;
policy->max = policy->cpuinfo.max_freq = 1000000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
return 0;
}
static struct cpufreq_driver ucv2_driver = {
.flags = CPUFREQ_STICKY,
.verify = ucv2_verify_speed,
.target = ucv2_target,
.get = ucv2_getspeed,
.init = ucv2_cpu_init,
.name = "UniCore-II",
};
static int __init ucv2_cpufreq_init(void)
{
return cpufreq_register_driver(&ucv2_driver);
}
arch_initcall(ucv2_cpufreq_init);

View File

@ -0,0 +1,89 @@
/*
* linux/arch/unicore32/kernel/debug-macro.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Debugging macro include header
*/
#include <generated/asm-offsets.h>
#include <mach/hardware.h>
.macro put_word_ocd, rd, rx=r16
1001: movc \rx, p1.c0, #0
cand.a \rx, #2
bne 1001b
movc p1.c1, \rd, #1
.endm
#ifdef CONFIG_DEBUG_OCD
/* debug using UniCore On-Chip-Debugger */
.macro addruart, rx
.endm
.macro senduart, rd, rx
put_word_ocd \rd, \rx
.endm
.macro busyuart, rd, rx
.endm
.macro waituart, rd, rx
.endm
#else
#define UART_CLK_DEFAULT 3686400 * 20
/* Uartclk = MCLK/ 2, The MCLK on my board is 3686400 * 40 */
#define BAUD_RATE_DEFAULT 115200
/* The baud rate of the serial port */
#define UART_DIVISOR_DEFAULT (UART_CLK_DEFAULT \
/ (16 * BAUD_RATE_DEFAULT) - 1)
.macro addruart,rx
mrc p0, #0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
moveq \rx, #0xee000000 @ physical base address
movne \rx, #0x6e000000 @ virtual address
@ We probe for the active serial port here
@ However, now we assume UART0 is active: epip4d
@ We assume r1 and r2 can be clobbered.
movl r2, #UART_DIVISOR_DEFAULT
mov r1, #0x80
str r1, [\rx, #UART_LCR_OFFSET]
and r1, r2, #0xff00
mov r1, r1, lsr #8
str r1, [\rx, #UART_DLH_OFFSET]
and r1, r2, #0xff
str r1, [\rx, #UART_DLL_OFFSET]
mov r1, #0x7
str r1, [\rx, #UART_FCR_OFFSET]
mov r1, #0x3
str r1, [\rx, #UART_LCR_OFFSET]
mov r1, #0x0
str r1, [\rx, #UART_IER_OFFSET]
.endm
.macro senduart,rd,rx
str \rd, [\rx, #UART_THR_OFFSET]
.endm
.macro waituart,rd,rx
1001: ldr \rd, [\rx, #UART_LSR_OFFSET]
tst \rd, #UART_LSR_THRE
beq 1001b
.endm
.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #UART_LSR_OFFSET]
tst \rd, #UART_LSR_TEMT
bne 1001b
.endm
#endif

View File

@ -0,0 +1,85 @@
/*
* linux/arch/unicore32/kernel/debug.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* 32-bit debugging code
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
/*
* Some debugging routines (useful if you've got MM problems and
* printk isn't working). For DEBUGGING ONLY!!! Do not leave
* references to these in a production kernel!
*/
#include "debug-macro.S"
/*
* Useful debugging routines
*/
ENTRY(printhex8)
mov r1, #8
b printhex
ENDPROC(printhex8)
ENTRY(printhex4)
mov r1, #4
b printhex
ENDPROC(printhex4)
ENTRY(printhex2)
mov r1, #2
printhex: adr r2, hexbuf
add r3, r2, r1
mov r1, #0
stb r1, [r3]
1: and r1, r0, #15
mov r0, r0 >> #4
csub.a r1, #10
beg 2f
add r1, r1, #'0' - 'a' + 10
2: add r1, r1, #'a' - 10
stb.w r1, [r3+], #-1
cxor.a r3, r2
bne 1b
mov r0, r2
b printascii
ENDPROC(printhex2)
.ltorg
ENTRY(printascii)
addruart r3
b 2f
1: waituart r2, r3
senduart r1, r3
busyuart r2, r3
cxor.a r1, #'\n'
cmoveq r1, #'\r'
beq 1b
2: cxor.a r0, #0
beq 3f
ldb.w r1, [r0]+, #1
cxor.a r1, #0
bne 1b
3: mov pc, lr
ENDPROC(printascii)
ENTRY(printch)
addruart r3
mov r1, r0
mov r0, #0
b 1b
ENDPROC(printch)
hexbuf: .space 16

183
arch/unicore32/kernel/dma.c Normal file
View File

@ -0,0 +1,183 @@
/*
* linux/arch/unicore32/kernel/dma.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/dma.h>
struct dma_channel {
char *name;
puv3_dma_prio prio;
void (*irq_handler)(int, void *);
void (*err_handler)(int, void *);
void *data;
};
static struct dma_channel dma_channels[MAX_DMA_CHANNELS];
int puv3_request_dma(char *name, puv3_dma_prio prio,
void (*irq_handler)(int, void *),
void (*err_handler)(int, void *),
void *data)
{
unsigned long flags;
int i, found = 0;
/* basic sanity checks */
if (!name)
return -EINVAL;
local_irq_save(flags);
do {
/* try grabbing a DMA channel with the requested priority */
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
if ((dma_channels[i].prio == prio) &&
!dma_channels[i].name) {
found = 1;
break;
}
}
/* if requested prio group is full, try a hier priority */
} while (!found && prio--);
if (found) {
dma_channels[i].name = name;
dma_channels[i].irq_handler = irq_handler;
dma_channels[i].err_handler = err_handler;
dma_channels[i].data = data;
} else {
printk(KERN_WARNING "No more available DMA channels for %s\n",
name);
i = -ENODEV;
}
local_irq_restore(flags);
return i;
}
EXPORT_SYMBOL(puv3_request_dma);
void puv3_free_dma(int dma_ch)
{
unsigned long flags;
if (!dma_channels[dma_ch].name) {
printk(KERN_CRIT
"%s: trying to free channel %d which is already freed\n",
__func__, dma_ch);
return;
}
local_irq_save(flags);
dma_channels[dma_ch].name = NULL;
dma_channels[dma_ch].err_handler = NULL;
local_irq_restore(flags);
}
EXPORT_SYMBOL(puv3_free_dma);
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
int i, dint;
dint = readl(DMAC_ITCSR);
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
if (dint & DMAC_CHANNEL(i)) {
struct dma_channel *channel = &dma_channels[i];
/* Clear TC interrupt of channel i */
writel(DMAC_CHANNEL(i), DMAC_ITCCR);
writel(0, DMAC_ITCCR);
if (channel->name && channel->irq_handler) {
channel->irq_handler(i, channel->data);
} else {
/*
* IRQ for an unregistered DMA channel:
* let's clear the interrupts and disable it.
*/
printk(KERN_WARNING "spurious IRQ for"
" DMA channel %d\n", i);
}
}
}
return IRQ_HANDLED;
}
static irqreturn_t dma_err_handler(int irq, void *dev_id)
{
int i, dint;
dint = readl(DMAC_IESR);
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
if (dint & DMAC_CHANNEL(i)) {
struct dma_channel *channel = &dma_channels[i];
/* Clear Err interrupt of channel i */
writel(DMAC_CHANNEL(i), DMAC_IECR);
writel(0, DMAC_IECR);
if (channel->name && channel->err_handler) {
channel->err_handler(i, channel->data);
} else {
/*
* IRQ for an unregistered DMA channel:
* let's clear the interrupts and disable it.
*/
printk(KERN_WARNING "spurious IRQ for"
" DMA channel %d\n", i);
}
}
}
return IRQ_HANDLED;
}
int __init puv3_init_dma(void)
{
int i, ret;
/* dma channel priorities on v8 processors:
* ch 0 - 1 <--> (0) DMA_PRIO_HIGH
* ch 2 - 3 <--> (1) DMA_PRIO_MEDIUM
* ch 4 - 5 <--> (2) DMA_PRIO_LOW
*/
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
puv3_stop_dma(i);
dma_channels[i].name = NULL;
dma_channels[i].prio = min((i & 0x7) >> 1, DMA_PRIO_LOW);
}
ret = request_irq(IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
if (ret) {
printk(KERN_CRIT "Can't register IRQ for DMA\n");
return ret;
}
ret = request_irq(IRQ_DMAERR, dma_err_handler, 0, "DMAERR", NULL);
if (ret) {
printk(KERN_CRIT "Can't register IRQ for DMAERR\n");
free_irq(IRQ_DMA, "DMA");
return ret;
}
return 0;
}
postcore_initcall(puv3_init_dma);

View File

@ -0,0 +1,59 @@
/*
* linux/arch/unicore32/kernel/early_printk.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/console.h>
#include <linux/init.h>
#include <linux/string.h>
#include <mach/ocd.h>
/* On-Chip-Debugger functions */
static void early_ocd_write(struct console *con, const char *s, unsigned n)
{
while (*s && n-- > 0) {
if (*s == '\n')
ocd_putc((int)'\r');
ocd_putc((int)*s);
s++;
}
}
static struct console early_ocd_console = {
.name = "earlyocd",
.write = early_ocd_write,
.flags = CON_PRINTBUFFER,
.index = -1,
};
/* Direct interface for emergencies */
static struct console *early_console = &early_ocd_console;
static int __initdata keep_early;
static int __init setup_early_printk(char *buf)
{
if (!buf)
return 0;
if (strstr(buf, "keep"))
keep_early = 1;
if (!strncmp(buf, "ocd", 3))
early_console = &early_ocd_console;
if (keep_early)
early_console->flags &= ~CON_BOOT;
else
early_console->flags |= CON_BOOT;
register_console(early_console);
return 0;
}
early_param("earlyprintk", setup_early_printk);

View File

@ -0,0 +1,38 @@
/*
* linux/arch/unicore32/kernel/elf.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/sched.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
int elf_check_arch(const struct elf32_hdr *x)
{
/* Make sure it's an UniCore executable */
if (x->e_machine != EM_UNICORE)
return 0;
/* Make sure the entry address is reasonable */
if (x->e_entry & 3)
return 0;
return 1;
}
EXPORT_SYMBOL(elf_check_arch);
void elf_set_personality(const struct elf32_hdr *x)
{
unsigned int personality = PER_LINUX;
set_personality(personality);
}
EXPORT_SYMBOL(elf_set_personality);

View File

@ -0,0 +1,824 @@
/*
* linux/arch/unicore32/kernel/entry.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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.
*
* Low-level vector interface routines
*/
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/unistd.h>
#include <generated/asm-offsets.h>
#include "debug-macro.S"
@
@ Most of the stack format comes from struct pt_regs, but with
@ the addition of 8 bytes for storing syscall args 5 and 6.
@
#define S_OFF 8
/*
* The SWI code relies on the fact that R0 is at the bottom of the stack
* (due to slow/fast restore user regs).
*/
#if S_R0 != 0
#error "Please fix"
#endif
.macro zero_fp
#ifdef CONFIG_FRAME_POINTER
mov fp, #0
#endif
.endm
.macro alignment_trap, rtemp
#ifdef CONFIG_ALIGNMENT_TRAP
ldw \rtemp, .LCcralign
ldw \rtemp, [\rtemp]
movc p0.c1, \rtemp, #0
#endif
.endm
.macro load_user_sp_lr, rd, rtemp, offset = 0
mov \rtemp, asr
xor \rtemp, \rtemp, #(PRIV_MODE ^ SUSR_MODE)
mov.a asr, \rtemp @ switch to the SUSR mode
ldw sp, [\rd+], #\offset @ load sp_user
ldw lr, [\rd+], #\offset + 4 @ load lr_user
xor \rtemp, \rtemp, #(PRIV_MODE ^ SUSR_MODE)
mov.a asr, \rtemp @ switch back to the PRIV mode
.endm
.macro priv_exit, rpsr
mov.a bsr, \rpsr
ldm.w (r0 - r15), [sp]+
ldm.b (r16 - pc), [sp]+ @ load r0 - pc, asr
.endm
.macro restore_user_regs, fast = 0, offset = 0
ldw r1, [sp+], #\offset + S_PSR @ get calling asr
ldw lr, [sp+], #\offset + S_PC @ get pc
mov.a bsr, r1 @ save in bsr_priv
.if \fast
add sp, sp, #\offset + S_R1 @ r0 is syscall return value
ldm.w (r1 - r15), [sp]+ @ get calling r1 - r15
ldur (r16 - lr), [sp]+ @ get calling r16 - lr
.else
ldm.w (r0 - r15), [sp]+ @ get calling r0 - r15
ldur (r16 - lr), [sp]+ @ get calling r16 - lr
.endif
nop
add sp, sp, #S_FRAME_SIZE - S_R16
mov.a pc, lr @ return
@ and move bsr_priv into asr
.endm
.macro get_thread_info, rd
mov \rd, sp >> #13
mov \rd, \rd << #13
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldw \base, =(PKUNITY_INTC_BASE)
ldw \irqstat, [\base+], #0xC @ INTC_ICIP
ldw \tmp, [\base+], #0x4 @ INTC_ICMR
and.a \irqstat, \irqstat, \tmp
beq 1001f
cntlz \irqnr, \irqstat
rsub \irqnr, \irqnr, #31
1001: /* EQ will be set if no irqs pending */
.endm
#ifdef CONFIG_DEBUG_LL
.macro printreg, reg, temp
adr \temp, 901f
stm (r0-r3), [\temp]+
stw lr, [\temp+], #0x10
mov r0, \reg
b.l printhex8
mov r0, #':'
b.l printch
mov r0, pc
b.l printhex8
adr r0, 902f
b.l printascii
adr \temp, 901f
ldm (r0-r3), [\temp]+
ldw lr, [\temp+], #0x10
b 903f
901: .word 0, 0, 0, 0, 0 @ r0-r3, lr
902: .asciz ": epip4d\n"
.align
903:
.endm
#endif
/*
* These are the registers used in the syscall handler, and allow us to
* have in theory up to 7 arguments to a function - r0 to r6.
*
* Note that tbl == why is intentional.
*
* We must set at least "tsk" and "why" when calling ret_with_reschedule.
*/
scno .req r21 @ syscall number
tbl .req r22 @ syscall table pointer
why .req r22 @ Linux syscall (!= 0)
tsk .req r23 @ current thread_info
/*
* Interrupt handling. Preserves r17, r18, r19
*/
.macro intr_handler
1: get_irqnr_and_base r0, r6, r5, lr
beq 2f
mov r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adr lr, 1b
b asm_do_IRQ
2:
.endm
/*
* PRIV mode handlers
*/
.macro priv_entry
sub sp, sp, #(S_FRAME_SIZE - 4)
stm (r1 - r15), [sp]+
add r5, sp, #S_R15
stm (r16 - r28), [r5]+
ldm (r1 - r3), [r0]+
add r5, sp, #S_SP - 4 @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
add r0, sp, #(S_FRAME_SIZE - 4)
stw.w r1, [sp+], #-4 @ save the "real" r0 copied
@ from the exception stack
mov r1, lr
@
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r0 - sp_priv
@ r1 - lr_priv
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - bsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
stm (r0 - r4), [r5]+
.endm
/*
* User mode handlers
*
*/
.macro user_entry
sub sp, sp, #S_FRAME_SIZE
stm (r1 - r15), [sp+]
add r4, sp, #S_R16
stm (r16 - r28), [r4]+
ldm (r1 - r3), [r0]+
add r0, sp, #S_PC @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
stw r1, [sp] @ save the "real" r0 copied
@ from the exception stack
@
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - bsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
@ Also, separately save sp_user and lr_user
@
stm (r2 - r4), [r0]+
stur (sp, lr), [r0-]
@
@ Enable the alignment trap while in kernel mode
@
alignment_trap r0
@
@ Clear FP to mark the first stack frame
@
zero_fp
.endm
.text
@
@ __invalid - generic code for failed exception
@ (re-entrant version of handlers)
@
__invalid:
sub sp, sp, #S_FRAME_SIZE
stm (r1 - r15), [sp+]
add r1, sp, #S_R16
stm (r16 - r28, sp, lr), [r1]+
zero_fp
ldm (r4 - r6), [r0]+
add r0, sp, #S_PC @ here for interlock avoidance
mov r7, #-1 @ "" "" "" ""
stw r4, [sp] @ save preserved r0
stm (r5 - r7), [r0]+ @ lr_<exception>,
@ asr_<exception>, "old_r0"
mov r0, sp
mov r1, asr
b bad_mode
ENDPROC(__invalid)
.align 5
__dabt_priv:
priv_entry
@
@ get ready to re-enable interrupts if appropriate
@
mov r17, asr
cand.a r3, #PSR_I_BIT
bne 1f
andn r17, r17, #PSR_I_BIT
1:
@
@ Call the processor-specific abort handler:
@
@ r2 - aborted context pc
@ r3 - aborted context asr
@
@ The abort handler must return the aborted address in r0, and
@ the fault status register in r1.
@
movc r1, p0.c3, #0 @ get FSR
movc r0, p0.c4, #0 @ get FAR
@
@ set desired INTR state, then call main handler
@
mov.a asr, r17
mov r2, sp
b.l do_DataAbort
@
@ INTRs off again before pulling preserved data off the stack
@
disable_irq r0
@
@ restore BSR and restart the instruction
@
ldw r2, [sp+], #S_PSR
priv_exit r2 @ return from exception
ENDPROC(__dabt_priv)
.align 5
__intr_priv:
priv_entry
intr_handler
mov r0, #0 @ epip4d
movc p0.c5, r0, #14
nop; nop; nop; nop; nop; nop; nop; nop
ldw r4, [sp+], #S_PSR @ irqs are already disabled
priv_exit r4 @ return from exception
ENDPROC(__intr_priv)
.ltorg
.align 5
__extn_priv:
priv_entry
mov r0, sp @ struct pt_regs *regs
mov r1, asr
b bad_mode @ not supported
ENDPROC(__extn_priv)
.align 5
__pabt_priv:
priv_entry
@
@ re-enable interrupts if appropriate
@
mov r17, asr
cand.a r3, #PSR_I_BIT
bne 1f
andn r17, r17, #PSR_I_BIT
1:
@
@ set args, then call main handler
@
@ r0 - address of faulting instruction
@ r1 - pointer to registers on stack
@
mov r0, r2 @ pass address of aborted instruction
mov r1, #5
mov.a asr, r17
mov r2, sp @ regs
b.l do_PrefetchAbort @ call abort handler
@
@ INTRs off again before pulling preserved data off the stack
@
disable_irq r0
@
@ restore BSR and restart the instruction
@
ldw r2, [sp+], #S_PSR
priv_exit r2 @ return from exception
ENDPROC(__pabt_priv)
.align 5
.LCcralign:
.word cr_alignment
.align 5
__dabt_user:
user_entry
#ifdef CONFIG_UNICORE_FPU_F64
cff ip, s31
cand.a ip, #0x08000000 @ FPU execption traps?
beq 209f
ldw ip, [sp+], #S_PC
add ip, ip, #4
stw ip, [sp+], #S_PC
@
@ fall through to the emulation code, which returns using r19 if
@ it has emulated the instruction, or the more conventional lr
@ if we are to treat this as a real extended instruction
@
@ r0 - instruction
@
1: ldw.u r0, [r2]
adr r19, ret_from_exception
adr lr, 209f
@
@ fallthrough to call do_uc_f64
@
/*
* Check whether the instruction is a co-processor instruction.
* If yes, we need to call the relevant co-processor handler.
*
* Note that we don't do a full check here for the co-processor
* instructions; all instructions with bit 27 set are well
* defined. The only instructions that should fault are the
* co-processor instructions.
*
* Emulators may wish to make use of the following registers:
* r0 = instruction opcode.
* r2 = PC
* r19 = normal "successful" return address
* r20 = this threads thread_info structure.
* lr = unrecognised instruction return address
*/
get_thread_info r20 @ get current thread
and r8, r0, #0x00003c00 @ mask out CP number
mov r7, #1
stb r7, [r20+], #TI_USED_CP + 2 @ set appropriate used_cp[]
@ F64 hardware support entry point.
@ r0 = faulted instruction
@ r19 = return address
@ r20 = fp_state
enable_irq r4
add r20, r20, #TI_FPSTATE @ r20 = workspace
cff r1, s31 @ get fpu FPSCR
andn r2, r1, #0x08000000
ctf r2, s31 @ clear 27 bit
mov r2, sp @ nothing stacked - regdump is at TOS
mov lr, r19 @ setup for a return to the user code
@ Now call the C code to package up the bounce to the support code
@ r0 holds the trigger instruction
@ r1 holds the FPSCR value
@ r2 pointer to register dump
b ucf64_exchandler
209:
#endif
@
@ Call the processor-specific abort handler:
@
@ r2 - aborted context pc
@ r3 - aborted context asr
@
@ The abort handler must return the aborted address in r0, and
@ the fault status register in r1.
@
movc r1, p0.c3, #0 @ get FSR
movc r0, p0.c4, #0 @ get FAR
@
@ INTRs on, then call the main handler
@
enable_irq r2
mov r2, sp
adr lr, ret_from_exception
b do_DataAbort
ENDPROC(__dabt_user)
.align 5
__intr_user:
user_entry
get_thread_info tsk
intr_handler
mov why, #0
b ret_to_user
ENDPROC(__intr_user)
.ltorg
.align 5
__extn_user:
user_entry
mov r0, sp
mov r1, asr
b bad_mode
ENDPROC(__extn_user)
.align 5
__pabt_user:
user_entry
mov r0, r2 @ pass address of aborted instruction.
mov r1, #5
enable_irq r1 @ Enable interrupts
mov r2, sp @ regs
b.l do_PrefetchAbort @ call abort handler
/* fall through */
/*
* This is the return code to user mode for abort handlers
*/
ENTRY(ret_from_exception)
get_thread_info tsk
mov why, #0
b ret_to_user
ENDPROC(__pabt_user)
ENDPROC(ret_from_exception)
/*
* Register switch for UniCore V2 processors
* r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
add ip, r1, #TI_CPU_SAVE
stm.w (r4 - r15), [ip]+
stm.w (r16 - r27, sp, lr), [ip]+
#ifdef CONFIG_UNICORE_FPU_F64
add ip, r1, #TI_FPSTATE
sfm.w (f0 - f7 ), [ip]+
sfm.w (f8 - f15), [ip]+
sfm.w (f16 - f23), [ip]+
sfm.w (f24 - f31), [ip]+
cff r4, s31
stw r4, [ip]
add ip, r2, #TI_FPSTATE
lfm.w (f0 - f7 ), [ip]+
lfm.w (f8 - f15), [ip]+
lfm.w (f16 - f23), [ip]+
lfm.w (f24 - f31), [ip]+
ldw r4, [ip]
ctf r4, s31
#endif
add ip, r2, #TI_CPU_SAVE
ldm.w (r4 - r15), [ip]+
ldm (r16 - r27, sp, pc), [ip]+ @ Load all regs saved previously
ENDPROC(__switch_to)
.align 5
/*
* This is the fast syscall return path. We do as little as
* possible here, and this includes saving r0 back into the PRIV
* stack.
*/
ret_fast_syscall:
disable_irq r1 @ disable interrupts
ldw r1, [tsk+], #TI_FLAGS
cand.a r1, #_TIF_WORK_MASK
bne fast_work_pending
@ fast_restore_user_regs
restore_user_regs fast = 1, offset = S_OFF
/*
* Ok, we need to do extra processing, enter the slow path.
*/
fast_work_pending:
stw.w r0, [sp+], #S_R0+S_OFF @ returned r0
work_pending:
cand.a r1, #_TIF_NEED_RESCHED
bne work_resched
cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
beq no_work_pending
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
cand.a r1, #_TIF_SIGPENDING @ delivering a signal?
cmovne why, #0 @ prevent further restarts
b.l do_notify_resume
b ret_slow_syscall @ Check work again
work_resched:
b.l schedule
/*
* "slow" syscall return path. "why" tells us if this was a real syscall.
*/
ENTRY(ret_to_user)
ret_slow_syscall:
disable_irq r1 @ disable interrupts
get_thread_info tsk @ epip4d, one path error?!
ldw r1, [tsk+], #TI_FLAGS
cand.a r1, #_TIF_WORK_MASK
bne work_pending
no_work_pending:
@ slow_restore_user_regs
restore_user_regs fast = 0, offset = 0
ENDPROC(ret_to_user)
/*
* This is how we return from a fork.
*/
ENTRY(ret_from_fork)
b.l schedule_tail
get_thread_info tsk
ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing
mov why, #1
cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
beq ret_slow_syscall
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
b.l syscall_trace
b ret_slow_syscall
ENDPROC(ret_from_fork)
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
*/
.align 5
ENTRY(vector_swi)
sub sp, sp, #S_FRAME_SIZE
stm (r0 - r15), [sp]+ @ Calling r0 - r15
add r8, sp, #S_R16
stm (r16 - r28), [r8]+ @ Calling r16 - r28
add r8, sp, #S_PC
stur (sp, lr), [r8-] @ Calling sp, lr
mov r8, bsr @ called from non-REAL mode
stw lr, [sp+], #S_PC @ Save calling PC
stw r8, [sp+], #S_PSR @ Save ASR
stw r0, [sp+], #S_OLD_R0 @ Save OLD_R0
zero_fp
/*
* Get the system call number.
*/
sub ip, lr, #4
ldw.u scno, [ip] @ get SWI instruction
#ifdef CONFIG_ALIGNMENT_TRAP
ldw ip, __cr_alignment
ldw ip, [ip]
movc p0.c1, ip, #0 @ update control register
#endif
enable_irq ip
get_thread_info tsk
ldw tbl, =sys_call_table @ load syscall table pointer
andn scno, scno, #0xff000000 @ mask off SWI op-code
andn scno, scno, #0x00ff0000 @ mask off SWI op-code
stm.w (r4, r5), [sp-] @ push fifth and sixth args
ldw ip, [tsk+], #TI_FLAGS @ check for syscall tracing
cand.a ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
csub.a scno, #__NR_syscalls @ check upper syscall limit
adr lr, ret_fast_syscall @ return address
bea 1f
ldw pc, [tbl+], scno << #2 @ call sys_* routine
1:
add r1, sp, #S_OFF
2: mov why, #0 @ no longer a real syscall
b sys_ni_syscall @ not private func
/*
* This is the really slow path. We're going to be doing
* context switches, and waiting for our parent to respond.
*/
__sys_trace:
mov r2, scno
add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0]
b.l syscall_trace
adr lr, __sys_trace_return @ return address
mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs
csub.a scno, #__NR_syscalls @ check upper syscall limit
bea 2b
ldm (r0 - r3), [r1]+ @ have to reload r0 - r3
ldw pc, [tbl+], scno << #2 @ call sys_* routine
__sys_trace_return:
stw.w r0, [sp+], #S_R0 + S_OFF @ save returned r0
mov r2, scno
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
b.l syscall_trace
b ret_slow_syscall
.align 5
#ifdef CONFIG_ALIGNMENT_TRAP
.type __cr_alignment, #object
__cr_alignment:
.word cr_alignment
#endif
.ltorg
ENTRY(sys_execve)
add r3, sp, #S_OFF
b __sys_execve
ENDPROC(sys_execve)
ENTRY(sys_clone)
add ip, sp, #S_OFF
stw ip, [sp+], #4
b __sys_clone
ENDPROC(sys_clone)
ENTRY(sys_rt_sigreturn)
add r0, sp, #S_OFF
mov why, #0 @ prevent syscall restart handling
b __sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn)
ENTRY(sys_sigaltstack)
ldw r2, [sp+], #S_OFF + S_SP
b do_sigaltstack
ENDPROC(sys_sigaltstack)
__INIT
/*
* Vector stubs.
*
* This code is copied to 0xffff0200 so we can use branches in the
* vectors, rather than ldr's. Note that this code must not
* exceed 0x300 bytes.
*
* Common stub entry macro:
* Enter in INTR mode, bsr = PRIV/USER ASR, lr = PRIV/USER PC
*
* SP points to a minimal amount of processor-private memory, the address
* of which is copied into r0 for the mode specific abort handler.
*/
.macro vector_stub, name, mode
.align 5
vector_\name:
@
@ Save r0, lr_<exception> (parent PC) and bsr_<exception>
@ (parent ASR)
@
stw r0, [sp]
stw lr, [sp+], #4 @ save r0, lr
mov lr, bsr
stw lr, [sp+], #8 @ save bsr
@
@ Prepare for PRIV mode. INTRs remain disabled.
@
mov r0, asr
xor r0, r0, #(\mode ^ PRIV_MODE)
mov.a bsr, r0
@
@ the branch table must immediately follow this code
@
and lr, lr, #0x03
add lr, lr, #1
mov r0, sp
ldw lr, [pc+], lr << #2
mov.a pc, lr @ branch to handler in PRIV mode
ENDPROC(vector_\name)
.align 2
@ handler addresses follow this label
.endm
.globl __stubs_start
__stubs_start:
/*
* Interrupt dispatcher
*/
vector_stub intr, INTR_MODE
.long __intr_user @ 0 (USER)
.long __invalid @ 1
.long __invalid @ 2
.long __intr_priv @ 3 (PRIV)
/*
* Data abort dispatcher
* Enter in ABT mode, bsr = USER ASR, lr = USER PC
*/
vector_stub dabt, ABRT_MODE
.long __dabt_user @ 0 (USER)
.long __invalid @ 1
.long __invalid @ 2 (INTR)
.long __dabt_priv @ 3 (PRIV)
/*
* Prefetch abort dispatcher
* Enter in ABT mode, bsr = USER ASR, lr = USER PC
*/
vector_stub pabt, ABRT_MODE
.long __pabt_user @ 0 (USER)
.long __invalid @ 1
.long __invalid @ 2 (INTR)
.long __pabt_priv @ 3 (PRIV)
/*
* Undef instr entry dispatcher
* Enter in EXTN mode, bsr = PRIV/USER ASR, lr = PRIV/USER PC
*/
vector_stub extn, EXTN_MODE
.long __extn_user @ 0 (USER)
.long __invalid @ 1
.long __invalid @ 2 (INTR)
.long __extn_priv @ 3 (PRIV)
/*
* We group all the following data together to optimise
* for CPUs with separate I & D caches.
*/
.align 5
.LCvswi:
.word vector_swi
.globl __stubs_end
__stubs_end:
.equ stubs_offset, __vectors_start + 0x200 - __stubs_start
.globl __vectors_start
__vectors_start:
jepriv SYS_ERROR0
b vector_extn + stubs_offset
ldw pc, .LCvswi + stubs_offset
b vector_pabt + stubs_offset
b vector_dabt + stubs_offset
jepriv SYS_ERROR0
b vector_intr + stubs_offset
jepriv SYS_ERROR0
.globl __vectors_end
__vectors_end:
.data
.globl cr_alignment
.globl cr_no_alignment
cr_alignment:
.space 4
cr_no_alignment:
.space 4

View File

@ -0,0 +1,126 @@
/*
* linux/arch/unicore32/kernel/fpu-ucf64.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/fpu-ucf64.h>
/*
* A special flag to tell the normalisation code not to normalise.
*/
#define F64_NAN_FLAG 0x100
/*
* A bit pattern used to indicate the initial (unset) value of the
* exception mask, in case nothing handles an instruction. This
* doesn't include the NAN flag, which get masked out before
* we check for an error.
*/
#define F64_EXCEPTION_ERROR ((u32)-1 & ~F64_NAN_FLAG)
/*
* Since we aren't building with -mfpu=f64, we need to code
* these instructions using their MRC/MCR equivalents.
*/
#define f64reg(_f64_) #_f64_
#define cff(_f64_) ({ \
u32 __v; \
asm("cff %0, " f64reg(_f64_) "@ fmrx %0, " #_f64_ \
: "=r" (__v) : : "cc"); \
__v; \
})
#define ctf(_f64_, _var_) \
asm("ctf %0, " f64reg(_f64_) "@ fmxr " #_f64_ ", %0" \
: : "r" (_var_) : "cc")
/*
* Raise a SIGFPE for the current process.
* sicode describes the signal being raised.
*/
void ucf64_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
{
siginfo_t info;
memset(&info, 0, sizeof(info));
info.si_signo = SIGFPE;
info.si_code = sicode;
info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
/*
* This is the same as NWFPE, because it's not clear what
* this is used for
*/
current->thread.error_code = 0;
current->thread.trap_no = 6;
send_sig_info(SIGFPE, &info, current);
}
/*
* Handle exceptions of UniCore-F64.
*/
void ucf64_exchandler(u32 inst, u32 fpexc, struct pt_regs *regs)
{
u32 tmp = fpexc;
u32 exc = F64_EXCEPTION_ERROR & fpexc;
pr_debug("UniCore-F64: instruction %08x fpscr %08x\n",
inst, fpexc);
if (exc & FPSCR_CMPINSTR_BIT) {
if (exc & FPSCR_CON)
tmp |= FPSCR_CON;
else
tmp &= ~(FPSCR_CON);
exc &= ~(FPSCR_CMPINSTR_BIT | FPSCR_CON);
} else {
pr_debug(KERN_ERR "UniCore-F64 Error: unhandled exceptions\n");
pr_debug(KERN_ERR "UniCore-F64 FPSCR 0x%08x INST 0x%08x\n",
cff(FPSCR), inst);
ucf64_raise_sigfpe(0, regs);
return;
}
/*
* Update the FPSCR with the additional exception flags.
* Comparison instructions always return at least one of
* these flags set.
*/
tmp &= ~(FPSCR_TRAP | FPSCR_IOS | FPSCR_OFS | FPSCR_UFS |
FPSCR_IXS | FPSCR_HIS | FPSCR_IOC | FPSCR_OFC |
FPSCR_UFC | FPSCR_IXC | FPSCR_HIC);
tmp |= exc;
ctf(FPSCR, tmp);
}
/*
* F64 support code initialisation.
*/
static int __init ucf64_init(void)
{
ctf(FPSCR, 0x0); /* FPSCR_UFE | FPSCR_NDE perhaps better */
printk(KERN_INFO "Enable UniCore-F64 support.\n");
return 0;
}
late_initcall(ucf64_init);

View File

@ -0,0 +1,122 @@
/*
* linux/arch/unicore32/kernel/gpio.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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.
*/
/* in FPGA, no GPIO support */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#ifdef CONFIG_LEDS
#include <linux/leds.h>
#include <linux/platform_device.h>
static const struct gpio_led puv3_gpio_leds[] = {
{ .name = "cpuhealth", .gpio = GPO_CPU_HEALTH, .active_low = 0,
.default_trigger = "heartbeat", },
{ .name = "hdd_led", .gpio = GPO_HDD_LED, .active_low = 1,
.default_trigger = "ide-disk", },
};
static const struct gpio_led_platform_data puv3_gpio_led_data = {
.num_leds = ARRAY_SIZE(puv3_gpio_leds),
.leds = (void *) puv3_gpio_leds,
};
static struct platform_device puv3_gpio_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = (void *) &puv3_gpio_led_data,
}
};
static int __init puv3_gpio_leds_init(void)
{
platform_device_register(&puv3_gpio_gpio_leds);
return 0;
}
device_initcall(puv3_gpio_leds_init);
#endif
static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset)
{
return readl(GPIO_GPLR) & GPIO_GPIO(offset);
}
static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
if (value)
writel(GPIO_GPIO(offset), GPIO_GPSR);
else
writel(GPIO_GPIO(offset), GPIO_GPCR);
}
static int puv3_direction_input(struct gpio_chip *chip, unsigned offset)
{
unsigned long flags;
local_irq_save(flags);
writel(readl(GPIO_GPDR) & ~GPIO_GPIO(offset), GPIO_GPDR);
local_irq_restore(flags);
return 0;
}
static int puv3_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
unsigned long flags;
local_irq_save(flags);
puv3_gpio_set(chip, offset, value);
writel(readl(GPIO_GPDR) | GPIO_GPIO(offset), GPIO_GPDR);
local_irq_restore(flags);
return 0;
}
static struct gpio_chip puv3_gpio_chip = {
.label = "gpio",
.direction_input = puv3_direction_input,
.direction_output = puv3_direction_output,
.set = puv3_gpio_set,
.get = puv3_gpio_get,
.base = 0,
.ngpio = GPIO_MAX + 1,
};
void __init puv3_init_gpio(void)
{
writel(GPIO_DIR, GPIO_GPDR);
#if defined(CONFIG_PUV3_NB0916) || defined(CONFIG_PUV3_SMW0919) \
|| defined(CONFIG_PUV3_DB0913)
gpio_set_value(GPO_WIFI_EN, 1);
gpio_set_value(GPO_HDD_LED, 1);
gpio_set_value(GPO_VGA_EN, 1);
gpio_set_value(GPO_LCD_EN, 1);
gpio_set_value(GPO_CAM_PWR_EN, 0);
gpio_set_value(GPO_LCD_VCC_EN, 1);
gpio_set_value(GPO_SOFT_OFF, 1);
gpio_set_value(GPO_BT_EN, 1);
gpio_set_value(GPO_FAN_ON, 0);
gpio_set_value(GPO_SPKR, 0);
gpio_set_value(GPO_CPU_HEALTH, 1);
gpio_set_value(GPO_LAN_SEL, 1);
/*
* DO NOT modify the GPO_SET_V1 and GPO_SET_V2 in kernel
* gpio_set_value(GPO_SET_V1, 1);
* gpio_set_value(GPO_SET_V2, 1);
*/
#endif
gpiochip_add(&puv3_gpio_chip);
}

View File

@ -0,0 +1,252 @@
/*
* linux/arch/unicore32/kernel/head.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
#include <asm/ptrace.h>
#include <generated/asm-offsets.h>
#include <asm/memory.h>
#include <asm/thread_info.h>
#include <asm/system.h>
#include <asm/pgtable-hwdef.h>
#if (PHYS_OFFSET & 0x003fffff)
#error "PHYS_OFFSET must be at an even 4MiB boundary!"
#endif
#define KERNEL_RAM_VADDR (PAGE_OFFSET + KERNEL_IMAGE_START)
#define KERNEL_RAM_PADDR (PHYS_OFFSET + KERNEL_IMAGE_START)
#define KERNEL_PGD_PADDR (KERNEL_RAM_PADDR - 0x1000)
#define KERNEL_PGD_VADDR (KERNEL_RAM_VADDR - 0x1000)
#define KERNEL_START KERNEL_RAM_VADDR
#define KERNEL_END _end
/*
* swapper_pg_dir is the virtual address of the initial page table.
* We place the page tables 4K below KERNEL_RAM_VADDR. Therefore, we must
* make sure that KERNEL_RAM_VADDR is correctly set. Currently, we expect
* the least significant 16 bits to be 0x8000, but we could probably
* relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x1000.
*/
#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
#endif
.globl swapper_pg_dir
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x1000
/*
* Kernel startup entry point.
* ---------------------------
*
* This is normally called from the decompressor code. The requirements
* are: MMU = off, D-cache = off, I-cache = dont care
*
* This code is mostly position independent, so if you link the kernel at
* 0xc0008000, you call this at __pa(0xc0008000).
*/
__HEAD
ENTRY(stext)
@ set asr
mov r0, #PRIV_MODE @ ensure priv mode
or r0, #PSR_R_BIT | PSR_I_BIT @ disable irqs
mov.a asr, r0
@ process identify
movc r0, p0.c0, #0 @ cpuid
movl r1, 0xff00ffff @ mask
movl r2, 0x4d000863 @ value
and r0, r1, r0
cxor.a r0, r2
bne __error_p @ invalid processor id
/*
* Clear the 4K level 1 swapper page table
*/
movl r0, #KERNEL_PGD_PADDR @ page table address
mov r1, #0
add r2, r0, #0x1000
101: stw.w r1, [r0]+, #4
stw.w r1, [r0]+, #4
stw.w r1, [r0]+, #4
stw.w r1, [r0]+, #4
cxor.a r0, r2
bne 101b
movl r4, #KERNEL_PGD_PADDR @ page table address
mov r7, #PMD_TYPE_SECT | PMD_PRESENT @ page size: section
or r7, r7, #PMD_SECT_CACHEABLE @ cacheable
or r7, r7, #PMD_SECT_READ | PMD_SECT_WRITE | PMD_SECT_EXEC
/*
* Create identity mapping for first 4MB of kernel to
* cater for the MMU enable. This identity mapping
* will be removed by paging_init(). We use our current program
* counter to determine corresponding section base address.
*/
mov r6, pc
mov r6, r6 >> #22 @ start of kernel section
or r1, r7, r6 << #22 @ flags + kernel base
stw r1, [r4+], r6 << #2 @ identity mapping
/*
* Now setup the pagetables for our kernel direct
* mapped region.
*/
add r0, r4, #(KERNEL_START & 0xff000000) >> 20
stw.w r1, [r0+], #(KERNEL_START & 0x00c00000) >> 20
movl r6, #(KERNEL_END - 1)
add r0, r0, #4
add r6, r4, r6 >> #20
102: csub.a r0, r6
add r1, r1, #1 << 22
bua 103f
stw.w r1, [r0]+, #4
b 102b
103:
/*
* Then map first 4MB of ram in case it contains our boot params.
*/
add r0, r4, #PAGE_OFFSET >> 20
or r6, r7, #(PHYS_OFFSET & 0xffc00000)
stw r6, [r0]
ldw r15, __switch_data @ address to jump to after
/*
* Initialise TLB, Caches, and MMU state ready to switch the MMU
* on.
*/
mov r0, #0
movc p0.c5, r0, #28 @ cache invalidate all
nop8
movc p0.c6, r0, #6 @ TLB invalidate all
nop8
/*
* ..V. .... ..TB IDAM
* ..1. .... ..01 1111
*/
movl r0, #0x201f @ control register setting
/*
* Setup common bits before finally enabling the MMU. Essentially
* this is just loading the page table pointer and domain access
* registers.
*/
#ifndef CONFIG_ALIGNMENT_TRAP
andn r0, r0, #CR_A
#endif
#ifdef CONFIG_CPU_DCACHE_DISABLE
andn r0, r0, #CR_D
#endif
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
andn r0, r0, #CR_B
#endif
#ifdef CONFIG_CPU_ICACHE_DISABLE
andn r0, r0, #CR_I
#endif
movc p0.c2, r4, #0 @ set pgd
b __turn_mmu_on
ENDPROC(stext)
/*
* Enable the MMU. This completely changes the stucture of the visible
* memory space. You will not be able to trace execution through this.
*
* r0 = cp#0 control register
* r15 = *virtual* address to jump to upon completion
*/
.align 5
__turn_mmu_on:
mov r0, r0
movc p0.c1, r0, #0 @ write control reg
nop @ fetch inst by phys addr
mov pc, r15
nop8 @ fetch inst by phys addr
ENDPROC(__turn_mmu_on)
/*
* Setup the initial page tables. We only setup the barest
* amount which are required to get the kernel running, which
* generally means mapping in the kernel code.
*
* r9 = cpuid
* r10 = procinfo
*
* Returns:
* r0, r3, r6, r7 corrupted
* r4 = physical page table address
*/
.ltorg
.align 2
.type __switch_data, %object
__switch_data:
.long __mmap_switched
.long __bss_start @ r6
.long _end @ r7
.long cr_alignment @ r8
.long init_thread_union + THREAD_START_SP @ sp
/*
* The following fragment of code is executed with the MMU on in MMU mode,
* and uses absolute addresses; this is not position independent.
*
* r0 = cp#0 control register
*/
__mmap_switched:
adr r3, __switch_data + 4
ldm.w (r6, r7, r8), [r3]+
ldw sp, [r3]
mov fp, #0 @ Clear BSS (and zero fp)
203: csub.a r6, r7
bea 204f
stw.w fp, [r6]+,#4
b 203b
204:
andn r1, r0, #CR_A @ Clear 'A' bit
stm (r0, r1), [r8]+ @ Save control register values
b start_kernel
ENDPROC(__mmap_switched)
/*
* Exception handling. Something went wrong and we can't proceed. We
* ought to tell the user, but since we don't have any guarantee that
* we're even running on the right architecture, we do virtually nothing.
*
* If CONFIG_DEBUG_LL is set we try to print out something about the error
* and hope for the best (useful if bootloader fails to pass a proper
* machine ID for example).
*/
__error_p:
#ifdef CONFIG_DEBUG_LL
adr r0, str_p1
b.l printascii
mov r0, r9
b.l printhex8
adr r0, str_p2
b.l printascii
901: nop8
b 901b
str_p1: .asciz "\nError: unrecognized processor variant (0x"
str_p2: .asciz ").\n"
.align
#endif
ENDPROC(__error_p)

View File

@ -0,0 +1,160 @@
/*
* linux/arch/unicore32/kernel/hibernate.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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/gfp.h>
#include <linux/suspend.h>
#include <linux/bootmem.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/suspend.h>
#include "mach/pm.h"
/* Pointer to the temporary resume page tables */
pgd_t *resume_pg_dir;
struct swsusp_arch_regs swsusp_arch_regs_cpu0;
/*
* Create a middle page table on a resume-safe page and put a pointer to it in
* the given global directory entry. This only returns the gd entry
* in non-PAE compilation mode, since the middle layer is folded.
*/
static pmd_t *resume_one_md_table_init(pgd_t *pgd)
{
pud_t *pud;
pmd_t *pmd_table;
pud = pud_offset(pgd, 0);
pmd_table = pmd_offset(pud, 0);
return pmd_table;
}
/*
* Create a page table on a resume-safe page and place a pointer to it in
* a middle page directory entry.
*/
static pte_t *resume_one_page_table_init(pmd_t *pmd)
{
if (pmd_none(*pmd)) {
pte_t *page_table = (pte_t *)get_safe_page(GFP_ATOMIC);
if (!page_table)
return NULL;
set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_KERNEL_TABLE));
BUG_ON(page_table != pte_offset_kernel(pmd, 0));
return page_table;
}
return pte_offset_kernel(pmd, 0);
}
/*
* This maps the physical memory to kernel virtual address space, a total
* of max_low_pfn pages, by creating page tables starting from address
* PAGE_OFFSET. The page tables are allocated out of resume-safe pages.
*/
static int resume_physical_mapping_init(pgd_t *pgd_base)
{
unsigned long pfn;
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
int pgd_idx, pmd_idx;
pgd_idx = pgd_index(PAGE_OFFSET);
pgd = pgd_base + pgd_idx;
pfn = 0;
for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
pmd = resume_one_md_table_init(pgd);
if (!pmd)
return -ENOMEM;
if (pfn >= max_low_pfn)
continue;
for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD; pmd++, pmd_idx++) {
pte_t *max_pte;
if (pfn >= max_low_pfn)
break;
/* Map with normal page tables.
* NOTE: We can mark everything as executable here
*/
pte = resume_one_page_table_init(pmd);
if (!pte)
return -ENOMEM;
max_pte = pte + PTRS_PER_PTE;
for (; pte < max_pte; pte++, pfn++) {
if (pfn >= max_low_pfn)
break;
set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
}
}
}
return 0;
}
static inline void resume_init_first_level_page_table(pgd_t *pg_dir)
{
}
int swsusp_arch_resume(void)
{
int error;
resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
if (!resume_pg_dir)
return -ENOMEM;
resume_init_first_level_page_table(resume_pg_dir);
error = resume_physical_mapping_init(resume_pg_dir);
if (error)
return error;
/* We have got enough memory and from now on we cannot recover */
restore_image(resume_pg_dir, restore_pblist);
return 0;
}
/*
* pfn_is_nosave - check if given pfn is in the 'nosave' section
*/
int pfn_is_nosave(unsigned long pfn)
{
unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
return (pfn >= begin_pfn) && (pfn < end_pfn);
}
void save_processor_state(void)
{
}
void restore_processor_state(void)
{
local_flush_tlb_all();
}

View File

@ -0,0 +1,117 @@
/*
* linux/arch/unicore32/kernel/hibernate_asm.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
* Copyright (C) 2001-2010 Guan Xuetao
*
* 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/sys.h>
#include <linux/errno.h>
#include <linux/linkage.h>
#include <generated/asm-offsets.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/assembler.h>
@ restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist)
@ r0: resume_pg_dir
@ r1: restore_pblist
@ copy restore_pblist pages
@ restore registers from swsusp_arch_regs_cpu0
@
ENTRY(restore_image)
sub r0, r0, #PAGE_OFFSET
mov r5, #0
movc p0.c6, r5, #6 @invalidate ITLB & DTLB
movc p0.c2, r0, #0
nop
nop
nop
nop
nop
nop
nop
.p2align 4,,7
101:
csub.a r1, #0
beq 109f
ldw r6, [r1+], #PBE_ADDRESS
ldw r7, [r1+], #PBE_ORIN_ADDRESS
movl ip, #128
102: ldm.w (r8 - r15), [r6]+
stm.w (r8 - r15), [r7]+
sub.a ip, ip, #1
bne 102b
ldw r1, [r1+], #PBE_NEXT
b 101b
.p2align 4,,7
109:
/* go back to the original page tables */
ldw r0, =swapper_pg_dir
sub r0, r0, #PAGE_OFFSET
mov r5, #0
movc p0.c6, r5, #6
movc p0.c2, r0, #0
nop
nop
nop
nop
nop
nop
nop
#ifdef CONFIG_UNICORE_FPU_F64
ldw ip, 1f
add ip, ip, #SWSUSP_FPSTATE
lfm.w (f0 - f7 ), [ip]+
lfm.w (f8 - f15), [ip]+
lfm.w (f16 - f23), [ip]+
lfm.w (f24 - f31), [ip]+
ldw r4, [ip]
ctf r4, s31
#endif
mov r0, #0x0
ldw ip, 1f
add ip, ip, #SWSUSP_CPU
ldm.w (r4 - r15), [ip]+
ldm (r16 - r27, sp, pc), [ip]+ @ Load all regs saved previously
.align 2
1: .long swsusp_arch_regs_cpu0
@ swsusp_arch_suspend()
@ - prepare pc for resume, return from function without swsusp_save on resume
@ - save registers in swsusp_arch_regs_cpu0
@ - call swsusp_save write suspend image
ENTRY(swsusp_arch_suspend)
ldw ip, 1f
add ip, ip, #SWSUSP_CPU
stm.w (r4 - r15), [ip]+
stm.w (r16 - r27, sp, lr), [ip]+
#ifdef CONFIG_UNICORE_FPU_F64
ldw ip, 1f
add ip, ip, #SWSUSP_FPSTATE
sfm.w (f0 - f7 ), [ip]+
sfm.w (f8 - f15), [ip]+
sfm.w (f16 - f23), [ip]+
sfm.w (f24 - f31), [ip]+
cff r4, s31
stw r4, [ip]
#endif
b swsusp_save @ no return
1: .long swsusp_arch_regs_cpu0

View File

@ -0,0 +1,44 @@
/*
* linux/arch/unicore32/kernel/init_task.c
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* 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/mm.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <linux/uaccess.h>
#include <asm/pgtable.h>
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
/*
* Initial thread structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
* the linker maps this in the .text segment right after head.S,
* and making head.S ensure the proper alignment.
*
* The things we do for performance..
*/
union thread_union init_thread_union __init_task_data = {
INIT_THREAD_INFO(init_task) };
/*
* Initial task structure.
*
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
EXPORT_SYMBOL(init_task);

Some files were not shown because too many files have changed in this diff Show More