Skip to content

Commit

Permalink
Merge tag 'for-4.5' of git://git.osdn.jp/gitroot/uclinux-h8/linux
Browse files Browse the repository at this point in the history
Pull h8300 updates from Yoshinori Sato:
 - Add KGDB support
 - zImage fix
 - various cleanup

* tag 'for-4.5' of git://git.osdn.jp/gitroot/uclinux-h8/linux:
  h8300: System call entry enable interrupt.
  h8300: show_stack cleanup
  h8300: Restraint of warning.
  h8300: Add KGDB support.
  irqchip: renesas-h8s: Replace ctrl_outw/ctrl_inw with writew/readw
  h8300: signal stack fix
  h8300: Add LZO compression
  h8300: zImage alignment fix
  clk: h8300: Remove "sh73a0-" part from compatible value
  h8300: zImage alignment fix
  • Loading branch information
torvalds committed Jan 21, 2016
2 parents 30f0530 + 2f1b007 commit 278e5ac
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Required Properties:

- compatible: Must be "renesas,sh73a0-h8300-div-clock"
- compatible: Must be "renesas,h8300-div-clock"

- clocks: Reference to the parent clocks ("extal1" and "extal2")

Expand Down
3 changes: 3 additions & 0 deletions arch/h8300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ config H8300
select HAVE_DMA_ATTRS
select CLKSRC_OF
select H8300_TMR8
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO
select HAVE_ARCH_KGDB

config RWSEM_GENERIC_SPINLOCK
def_bool y
Expand Down
11 changes: 8 additions & 3 deletions arch/h8300/boot/compressed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)

$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
suffix-$(CONFIG_KERNEL_GZIP) := gzip
suffix-$(CONFIG_KERNEL_LZO) := lzo

$(obj)/vmlinux.bin.$(suffix-y): $(obj)/vmlinux.bin FORCE
$(call if_changed,$(suffix-y))

LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300-linux -T
OBJCOPYFLAGS := -O binary

$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
$(call if_changed,ld)

CFLAGS_misc.o = -O0
6 changes: 6 additions & 0 deletions arch/h8300/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ extern char output[];

#define HEAP_SIZE 0x10000

#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif

#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif

void *memset(void *s, int c, size_t n)
{
Expand Down
4 changes: 3 additions & 1 deletion arch/h8300/boot/compressed/vmlinux.lds
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ SECTIONS
{
*(.rodata)
}
. = ALIGN(0x4) ;
.data :

{
. = ALIGN(0x4) ;
__sdata = . ;
___data_start = . ;
*(.data.*)
}
. = ALIGN(0x4) ;
.bss :
{
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss*)
. = ALIGN(0x4) ;
Expand Down
8 changes: 4 additions & 4 deletions arch/h8300/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ static inline void __raw_writel(u32 b, const volatile void __iomem *addr)
static inline void ctrl_bclr(int b, void __iomem *addr)
{
if (__builtin_constant_p(b))
__asm__("bclr %1,%0" : "+WU"(*addr): "i"(b));
__asm__("bclr %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
else
__asm__("bclr %w1,%0" : "+WU"(*addr): "r"(b));
__asm__("bclr %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
}

static inline void ctrl_bset(int b, void __iomem *addr)
{
if (__builtin_constant_p(b))
__asm__("bset %1,%0" : "+WU"(*addr): "i"(b));
__asm__("bset %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
else
__asm__("bset %w1,%0" : "+WU"(*addr): "r"(b));
__asm__("bset %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
}

#include <asm-generic/io.h>
Expand Down
45 changes: 45 additions & 0 deletions arch/h8300/include/asm/kgdb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Yoshinori Sato <[email protected]>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/

#ifndef _ASM_H8300_KGDB_H
#define _ASM_H8300_KGDB_H

#define CACHE_FLUSH_IS_SAFE 1
#define BUFMAX 2048

enum regnames {
GDB_ER0, GDB_ER1, GDB_ER2, GDB_ER3,
GDB_ER4, GDB_ER5, GDB_ER6, GDB_SP,
GDB_CCR, GDB_PC,
GDB_CYCLLE,
#if defined(CONFIG_CPU_H8S)
GDB_EXR,
#endif
GDB_TICK, GDB_INST,
#if defined(CONFIG_CPU_H8S)
GDB_MACH, GDB_MACL,
#endif
/* do not change the last entry or anything below! */
GDB_NUMREGBYTES, /* number of registers */
};

#define GDB_SIZEOF_REG sizeof(u32)
#if defined(CONFIG_CPU_H8300H)
#define DBG_MAX_REG_NUM (13)
#elif defined(CONFIG_CPU_H8S)
#define DBG_MAX_REG_NUM (14)
#endif
#define NUMREGBYTES (DBG_MAX_REG_NUM * GDB_SIZEOF_REG)

#define BREAK_INSTR_SIZE 2
static inline void arch_kgdb_breakpoint(void)
{
__asm__ __volatile__("trapa #2");
}

#endif /* _ASM_H8300_KGDB_H */
2 changes: 1 addition & 1 deletion arch/h8300/include/asm/traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ extern unsigned long *_interrupt_redirect_table;
extern char _start, _etext;
#define check_kernel_text(addr) \
((addr >= (unsigned long)(&_start)) && \
(addr < (unsigned long)(&_etext)))
(addr < (unsigned long)(&_etext)) && !(addr & 1))

#endif /* _H8300_TRAPS_H */
2 changes: 2 additions & 0 deletions arch/h8300/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ obj-$(CONFIG_H8S_SIM) += sim-console.o

obj-$(CONFIG_CPU_H8300H) += ptrace_h.o
obj-$(CONFIG_CPU_H8S) += ptrace_s.o

obj-$(CONFIG_KGDB) += kgdb.o
19 changes: 19 additions & 0 deletions arch/h8300/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ _interrupt_redirect_table:
jsr @_interrupt_entry /* NMI */
jmp @_system_call /* TRAPA #0 (System call) */
.long 0
#if defined(CONFIG_KGDB)
jmp @_kgdb_trap
#else
.long 0
#endif
jmp @_trace_break /* TRAPA #3 (breakpoint) */
.rept INTERRUPTS-12
jsr @_interrupt_entry
Expand Down Expand Up @@ -242,6 +246,7 @@ _system_call:
/* save top of frame */
mov.l sp,er0
jsr @set_esp0
andc #0x3f,ccr
mov.l sp,er2
and.w #0xe000,r2
mov.l @(TI_FLAGS:16,er2),er2
Expand Down Expand Up @@ -405,6 +410,20 @@ _nmi:
mov.l @sp+, er0
jmp @_interrupt_entry

#if defined(CONFIG_KGDB)
_kgdb_trap:
subs #4,sp
SAVE_ALL
mov.l sp,er0
add.l #LRET,er0
mov.l er0,@(LSP,sp)
jsr @set_esp0
mov.l sp,er0
subs #4,er0
jsr @h8300_kgdb_trap
jmp @ret_from_exception
#endif

.section .bss
_sw_ksp:
.space 4
Expand Down
135 changes: 135 additions & 0 deletions arch/h8300/kernel/kgdb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* H8/300 KGDB support
*
* Copyright (C) 2015 Yoshinori Sato <[email protected]>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/

#include <linux/ptrace.h>
#include <linux/kgdb.h>
#include <linux/kdebug.h>
#include <linux/io.h>

struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "er0", GDB_SIZEOF_REG, offsetof(struct pt_regs, er0) },
{ "er1", GDB_SIZEOF_REG, offsetof(struct pt_regs, er1) },
{ "er2", GDB_SIZEOF_REG, offsetof(struct pt_regs, er2) },
{ "er3", GDB_SIZEOF_REG, offsetof(struct pt_regs, er3) },
{ "er4", GDB_SIZEOF_REG, offsetof(struct pt_regs, er4) },
{ "er5", GDB_SIZEOF_REG, offsetof(struct pt_regs, er5) },
{ "er6", GDB_SIZEOF_REG, offsetof(struct pt_regs, er6) },
{ "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
{ "ccr", GDB_SIZEOF_REG, offsetof(struct pt_regs, ccr) },
{ "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, pc) },
{ "cycles", GDB_SIZEOF_REG, -1 },
#if defined(CONFIG_CPU_H8S)
{ "exr", GDB_SIZEOF_REG, offsetof(struct pt_regs, exr) },
#endif
{ "tick", GDB_SIZEOF_REG, -1 },
{ "inst", GDB_SIZEOF_REG, -1 },
};

char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
{
if (regno >= DBG_MAX_REG_NUM || regno < 0)
return NULL;

switch (regno) {
case GDB_CCR:
#if defined(CONFIG_CPU_H8S)
case GDB_EXR:
#endif
*(u32 *)mem = *(u16 *)((void *)regs +
dbg_reg_def[regno].offset);
break;
default:
if (dbg_reg_def[regno].offset >= 0)
memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
dbg_reg_def[regno].size);
else
memset(mem, 0, dbg_reg_def[regno].size);
break;
}
return dbg_reg_def[regno].name;
}

int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
{
if (regno >= DBG_MAX_REG_NUM || regno < 0)
return -EINVAL;

switch (regno) {
case GDB_CCR:
#if defined(CONFIG_CPU_H8S)
case GDB_EXR:
#endif
*(u16 *)((void *)regs +
dbg_reg_def[regno].offset) = *(u32 *)mem;
break;
default:
memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
dbg_reg_def[regno].size);
}
return 0;
}

asmlinkage void h8300_kgdb_trap(struct pt_regs *regs)
{
regs->pc &= 0x00ffffff;
if (kgdb_handle_exception(10, SIGTRAP, 0, regs))
return;
if (*(u16 *)(regs->pc) == *(u16 *)&arch_kgdb_ops.gdb_bpt_instr)
regs->pc += BREAK_INSTR_SIZE;
regs->pc |= regs->ccr << 24;
}

void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{
memset((char *)gdb_regs, 0, NUMREGBYTES);
gdb_regs[GDB_SP] = p->thread.ksp;
gdb_regs[GDB_PC] = KSTK_EIP(p);
}

void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
{
regs->pc = pc;
}

int kgdb_arch_handle_exception(int vector, int signo, int err_code,
char *remcom_in_buffer, char *remcom_out_buffer,
struct pt_regs *regs)
{
char *ptr;
unsigned long addr;

switch (remcom_in_buffer[0]) {
case 's':
case 'c':
/* handle the optional parameters */
ptr = &remcom_in_buffer[1];
if (kgdb_hex2long(&ptr, &addr))
regs->pc = addr;

return 0;
}

return -1; /* this means that we do not want to exit from the handler */
}

int kgdb_arch_init(void)
{
return 0;
}

void kgdb_arch_exit(void)
{
/* Nothing to do */
}

const struct kgdb_arch arch_kgdb_ops = {
/* Breakpoint instruction: trapa #2 */
.gdb_bpt_instr = { 0x57, 0x20 },
};
8 changes: 4 additions & 4 deletions arch/h8300/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
regs->ccr |= ccr;
regs->orig_er0 = -1; /* disable syscall checks */
err |= __get_user(usp, &usc->sc_usp);
wrusp(usp);
regs->sp = usp;

err |= __get_user(er0, &usc->sc_er0);
*pd0 = er0;
Expand Down Expand Up @@ -180,7 +180,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT;

/* Set up to return from userspace. */
ret = frame->retcode;
ret = (unsigned char *)&frame->retcode;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
else {
Expand All @@ -196,8 +196,8 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT;

/* Set up registers for signal handler */
wrusp((unsigned long) frame);
regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->sp = (unsigned long)frame;
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
regs->er0 = ksig->sig;
regs->er1 = (unsigned long)&(frame->info);
regs->er2 = (unsigned long)&frame->uc;
Expand Down
Loading

0 comments on commit 278e5ac

Please sign in to comment.