OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /altor32/trunk
    from Rev 42 to Rev 43
    Reverse comparison

Rev 42 → Rev 43

/sw/gdb_stub/gdb_hw.h
0,0 → 1,12
#ifndef __GDB_HW_H__
#define __GDB_HW_H__
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
void gdb_putchar(char c);
void gdb_putstr(const char *str);
int gdb_getchar(void);
void gdb_flush_cache(void);
 
#endif
/sw/gdb_stub/mem_map.h
0,0 → 1,49
#ifndef __MEM_MAP_H__
#define __MEM_MAP_H__
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define IO_BASE 0x12000000
 
//-----------------------------------------------------------------
// Macros:
//-----------------------------------------------------------------
#define REG8 (volatile unsigned char*)
#define REG16 (volatile unsigned short*)
#define REG32 (volatile unsigned int*)
 
//-----------------------------------------------------------------
// Peripheral Base Addresses
//-----------------------------------------------------------------
#define UART_BASE (IO_BASE + 0x000)
#define TIMER_BASE (IO_BASE + 0x100)
#define INTR_BASE (IO_BASE + 0x200)
 
//-----------------------------------------------------------------
// Interrupts
//-----------------------------------------------------------------
#define IRQ_UART_RX 0
#define IRQ_TIMER_SYSTICK 1
#define IRQ_TIMER_HIRES 2
#define IRQ_EXT_INT0 8
 
//-----------------------------------------------------------------
// Peripheral Registers
//-----------------------------------------------------------------
 
// UART
#define UART_USR (*(REG32 (UART_BASE + 0x4)))
#define UART_UDR (*(REG32 (UART_BASE + 0x8)))
 
// TIMER
#define TIMER_VAL (*(REG32 (TIMER_BASE + 0x0)))
#define SYS_CLK_COUNT (*(REG32 (TIMER_BASE + 0x4)))
 
// IRQ
#define IRQ_MASK (*(REG32 (INTR_BASE + 0x00)))
#define IRQ_MASK_SET (*(REG32 (INTR_BASE + 0x00)))
#define IRQ_MASK_CLR (*(REG32 (INTR_BASE + 0x04)))
#define IRQ_STATUS (*(REG32 (INTR_BASE + 0x08)))
 
#endif
/sw/gdb_stub/gdb.h
0,0 → 1,10
#ifndef __GDB_H__
#define __GDB_H__
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
void gdb_main(void);
unsigned int* gdb_exception(unsigned int *registers, unsigned int reason);
 
#endif
/sw/gdb_stub/boot.S
0,0 → 1,123
.nodelay
 
#include "exception.inc"
 
#-------------------------------------------------------------
# VECTOR 0x100 - Reset
#-------------------------------------------------------------
.org 0x100
vector_reset:
 
# Setup SP (R1)
l.movhi r4,hi(_sp);
l.ori r1,r4,lo(_sp);
# R4 = _bss_start
l.movhi r4,hi(_bss_start);
l.ori r4,r4,lo(_bss_start);
# R5 = _bss_end
l.movhi r5,hi(_bss_end);
l.ori r5,r5,lo(_bss_end);
BSS_CLEAR:
l.sw 0x0(r4),r0 # Write 0x00 to mem[r4]
l.sfleu r4,r5 # SR[F] = (r4 < r5)
l.addi r4, r4, 4 # r4 += 4
l.bf BSS_CLEAR # If SR[F] == 0, jump to BSS_CLEAR
l.nop
 
# Jump to debug agent
l.j gdb_main
l.nop
 
.size vector_reset, .-vector_reset
 
#-------------------------------------------------------------
# VECTOR 0x200 - Fault / Illegal Instruction
#-------------------------------------------------------------
.org 0x200
vector_fault:
 
# Save context
asm_save_context
 
# Arg 2 = Fault
l.addi r4, r0, 1
 
l.j handle_exception
l.nop
 
.size vector_fault, .-vector_fault
 
#-------------------------------------------------------------
# VECTOR 0x300 - External Interrupt
#-------------------------------------------------------------
.org 0x300
vector_extint:
 
# Save context
asm_save_context
 
# Arg 2 = Ext Int
l.addi r4, r0, 2
 
l.j handle_exception
l.nop
 
.size vector_extint, .-vector_extint
 
#-------------------------------------------------------------
# VECTOR 0x400 - Syscall
#-------------------------------------------------------------
.org 0x400
vector_syscall:
 
# Save context
asm_save_context
 
# Arg 2 = Syscall
l.addi r4, r0, 3
 
l.j handle_exception
l.nop
 
.size vector_syscall, .-vector_syscall
 
#-------------------------------------------------------------
# VECTOR 0x600 - Trap
#-------------------------------------------------------------
.org 0x600
vector_trap:
 
# Save context
asm_save_context
# Arg 2 = Trap
l.addi r4, r0, 4
 
# Fall through...
 
.size vector_trap, .-vector_trap
 
#-------------------------------------------------------------
# handle_exception: Common exception handling code
#-------------------------------------------------------------
handle_exception:
 
# Copy stack pointer to arg1
l.add r3, r0, r1
 
# Jump to debug handler
l.movhi r10,hi(gdb_exception);
l.ori r10,r10,lo(gdb_exception);
l.jalr r10
l.nop
 
# Return value is stack pointer
l.add r1, r0, r11
 
# Restore context
asm_load_context
 
.size handle_exception, .-handle_exception
/sw/gdb_stub/exception.inc
0,0 → 1,157
#-------------------------------------------------------------
# Context Stack Frame - 140 bytes / 35 words
#-------------------------------------------------------------
# 0: R0
# 4: R1 (SP)
# 8: R2
# 12: R3 (ARG0)
# 16: R4
# 20: R5
# 24: R6
# 28: R7
# 32: R8
# 36: R9 (LR)
# 40: R10
# 44: R11
# 48: R12
# 52: R13
# 56: R14
# 60: R15
# 64: R16
# 68: R17
# 72: R18
# 76: R19
# 80: R20
# 84: R21
# 88: R22
# 92: R23
# 96: R24
# 100: R25
# 104: R26
# 108: R27
# 112: R28
# 116: R29
# 120: R30
# 124: R31
# 128: X
# 132: EPC
# 136: ESR
#-------------------------------------------------------------
 
#-------------------------------------------------------------
# asm_save_context:
#-------------------------------------------------------------
.macro asm_save_context
l.nop
l.nop
# Adjust SP (frame size is 140 + allow for 128 uncommitted in-use stack)
l.addi r1, r1, -268
# Save register file to stack
l.sw 124(r1), r31
l.sw 120(r1), r30
l.sw 116(r1), r29
l.sw 112(r1), r28
l.sw 108(r1), r27
l.sw 104(r1), r26
l.sw 100(r1), r25
l.sw 96(r1), r24
l.sw 92(r1), r23
l.sw 88(r1), r22
l.sw 84(r1), r21
l.sw 80(r1), r20
l.sw 76(r1), r19
l.sw 72(r1), r18
l.sw 68(r1), r17
l.sw 64(r1), r16
l.sw 60(r1), r15
l.sw 56(r1), r14
l.sw 52(r1), r13
l.sw 48(r1), r12
l.sw 44(r1), r11
l.sw 40(r1), r10
l.sw 36(r1), r9
l.sw 32(r1), r8
l.sw 28(r1), r7
l.sw 24(r1), r6
l.sw 20(r1), r5
l.sw 16(r1), r4
l.sw 12(r1), r3
l.sw 8(r1), r2
l.sw 0(r1), r0
 
# R10 = EPC
l.mfspr r10, r0, 32
l.sw 132(r1), r10
 
# R10 = ESR
l.mfspr r10, r0, 64
l.sw 136(r1), r10
 
# Stack pointer (R1)
l.or r10, r0, r1
l.addi r10, r10, +268
l.sw 4(r1), r10
 
.endm
 
#-------------------------------------------------------------
# asm_load_context:
#-------------------------------------------------------------
.macro asm_load_context
 
# Restore EPC (PC of non-exception code)
l.lwz r10, 132(r1)
# EPC = R10
l.mtspr r0,r10,32
# Restore ESR (SR of non-exception code)
l.lwz r10, 136(r1)
# ESR = R10
l.mtspr r0,r10,64
# Restore register set
# r1/r1 already set
l.lwz r2, 8(r1)
l.lwz r3, 12(r1)
l.lwz r4, 16(r1)
l.lwz r5, 20(r1)
l.lwz r6, 24(r1)
l.lwz r7, 28(r1)
l.lwz r8, 32(r1)
l.lwz r9, 36(r1)
l.lwz r10, 40(r1)
l.lwz r11, 44(r1)
l.lwz r12, 48(r1)
l.lwz r13, 52(r1)
l.lwz r14, 56(r1)
l.lwz r15, 60(r1)
l.lwz r16, 64(r1)
l.lwz r17, 68(r1)
l.lwz r18, 72(r1)
l.lwz r19, 76(r1)
l.lwz r20, 80(r1)
l.lwz r21, 84(r1)
l.lwz r22, 88(r1)
l.lwz r23, 92(r1)
l.lwz r24, 96(r1)
l.lwz r25,100(r1)
l.lwz r26,104(r1)
l.lwz r27,108(r1)
l.lwz r28,112(r1)
l.lwz r29,116(r1)
l.lwz r30,120(r1)
l.lwz r31,124(r1)
# Adjust SP past register set
l.addi r1, r1, +268
# Return from interrupt (to restore PC & SR)
l.rfe
l.nop
 
.endm
/sw/gdb_stub/linker_script
0,0 → 1,53
GROUP("libgcc.a")
 
MEMORY
{
sram (rwx) : ORIGIN = 0x10000000, LENGTH = 8K
}
 
SECTIONS
{
.text :
{
_text_start = .;
*(.text .text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.rdata*)
. = ALIGN(4);
_text_end = .;
} > sram
.data :
{
. = ALIGN(4);
_data_start = .;
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(16);
. = ALIGN (8);
*(.ram)
*(.eh_frame)
. = ALIGN (8);
_edata = .;
_data_end = .;
} > sram
.bss :
{
. = ALIGN(4);
_bss_start = . ;
 
*(.bss*)
*(COMMON)
/* Allocate room for stack */
. = ALIGN(8) ;
. += 1024 ;
_sp = . - 16;
_bss_end = .;
} > sram
}
/sw/gdb_stub/gdb_hw.c
0,0 → 1,136
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// V2.0
// Ultra-Embedded.com
// Copyright 2011 - 2014
//
// Email: admin@ultra-embedded.com
//
// License: LGPL
//-----------------------------------------------------------------
//
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
// Boston, MA 02111-1307 USA
//-----------------------------------------------------------------
#include "mem_map.h"
#include "gdb_hw.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define UART_RX_AVAIL (1<<0)
#define UART_TX_AVAIL (1<<1)
#define UART_RX_FULL (1<<2)
#define UART_TX_BUSY (1<<3)
#define UART_RX_ERROR (1<<4)
 
// SR Register
#define SPR_SR (17)
#define SPR_SR_ICACHE_FLUSH (1 << 17)
#define SPR_SR_DCACHE_FLUSH (1 << 18)
 
#define MAX_RX_BUF 128
static char _rx_buf[MAX_RX_BUF];
static int _rx_head;
static int _rx_tail;
 
//-----------------------------------------------------------------
// mfspr: Read from SPR
//-----------------------------------------------------------------
static inline unsigned long mfspr(unsigned long spr)
{
unsigned long value;
asm volatile ("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
return value;
}
//-----------------------------------------------------------------
// mtspr: Write to SPR
//-----------------------------------------------------------------
static inline void mtspr(unsigned long spr, unsigned long value)
{
asm volatile ("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
}
//-----------------------------------------------------------------
// gdb_pollrx:
//-----------------------------------------------------------------
void gdb_pollrx (void)
{
if (UART_USR & UART_RX_AVAIL)
{
_rx_buf[_rx_tail] = UART_UDR;
 
if (++_rx_tail == MAX_RX_BUF)
_rx_tail = 0;
}
}
//-----------------------------------------------------------------
// gdb_putchar:
//-----------------------------------------------------------------
void gdb_putchar (char c)
{
UART_UDR = c;
while (UART_USR & UART_TX_BUSY)
gdb_pollrx();
}
//-------------------------------------------------------------
// gdb_putstr:
//-------------------------------------------------------------
void gdb_putstr(const char *str)
{
while (*str)
gdb_putchar(*str++);
}
//-----------------------------------------------------------------
// gdb_getchar:
//-----------------------------------------------------------------
int gdb_getchar (void)
{
int ch = -1;
 
do
{
gdb_pollrx();
 
if (_rx_head != _rx_tail)
{
ch = _rx_buf[_rx_head];
 
if (++_rx_head == MAX_RX_BUF)
_rx_head = 0;
 
break;
}
}
while (1);
 
return ch;
}
//-----------------------------------------------------------------
// gdb_flush_cache:
//-----------------------------------------------------------------
void gdb_flush_cache(void)
{
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICACHE_FLUSH | SPR_SR_DCACHE_FLUSH);
}
/sw/gdb_stub/gdb.c
0,0 → 1,554
//-----------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// V2.0
// Ultra-Embedded.com
// Copyright 2011 - 2014
//
// Email: admin@ultra-embedded.com
//
// License: LGPL
//-----------------------------------------------------------------
//
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
//
// This source file may be used and distributed without
// restriction provided that this copyright statement is not
// removed from the file and that any derivative work contains
// the original copyright notice and the associated disclaimer.
//
// This source file is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any
// later version.
//
// This source is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General
// Public License along with this source; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
// Boston, MA 02111-1307 USA
//-----------------------------------------------------------------
#include "gdb_hw.h"
#include "gdb.h"
 
//-----------------------------------------------------------------
// Defines
//-----------------------------------------------------------------
// Rx / Tx buffer max size
#define MAX_BUF_SIZE 512
 
// OR1K exception reasons
#define OR32_EXC_RESET 0
#define OR32_EXC_FAULT 1
#define OR32_EXC_INT 2
#define OR32_EXC_SYSCALL 3
#define OR32_EXC_BREAKPOINT 4
#define OR32_EXC_BUS_ERROR 6
 
#define OR32_SR_STEP 19
#define OR32_SR_DBGEN 20
 
#define GDB_SIGHUP 1
#define GDB_SIGINT 2
#define GDB_SIGTRAP 5
#define GDB_SIGSEGV 11
 
#define REG_SP 1
#define REG_ARG0 3
#define REG_ARG1 4
#define REG_PC 33
#define REG_SR 34
#define REG_NUM 35
 
//-----------------------------------------------------------------
// Locals
//-----------------------------------------------------------------
static char _inbuffer[MAX_BUF_SIZE];
static char _outbuffer[MAX_BUF_SIZE];
static int _initial_trap;
static const char _hex_char[] = "0123456789abcdef";
 
static unsigned int * (*syscall_handler)(unsigned int *registers);
static unsigned int * (*irq_handler)(unsigned int *registers);
 
//-----------------------------------------------------------------
// gdb_atoi_hex: Convert from hex character to integer
//-----------------------------------------------------------------
static int gdb_atoi_hex(char ch)
{
if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
else if (ch >= '0' && ch <= '9')
return ch - '0';
else if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
return -1;
}
//-----------------------------------------------------------------
// gdb_strcpy: String copy (avoid using any library functions)
//-----------------------------------------------------------------
static void gdb_strcpy(char *buf, const char *s)
{
while (*s)
*buf++ = *s++;
*buf = 0;
}
//-----------------------------------------------------------------
// gdb_mem2hex: Convert block of memory to ASCII
//-----------------------------------------------------------------
static char *gdb_mem2hex(unsigned char *mem, char *target, int count)
{
while (count)
{
*target++ = _hex_char[((*mem) >> 4) & 0xf];
*target++ = _hex_char[((*mem) >> 0) & 0xf];
mem++;
count--;
}
 
*target = 0;
return target;
}
//-----------------------------------------------------------------
// gdb_hex2mem: Convert ASCII hex string to binary
//-----------------------------------------------------------------
static char *gdb_hex2mem(char *src, unsigned char *mem, int count)
{
unsigned char ch;
 
while (count)
{
ch = gdb_atoi_hex(*src++) << 4;
ch |= gdb_atoi_hex(*src++) << 0;
 
*mem++ = ch;
count--;
}
 
return (char *)mem;
}
//-----------------------------------------------------------------
// gdb_gethexword: Convert ASCII hex word to integer
//-----------------------------------------------------------------
static int gdb_gethexword(char **s, unsigned int *val)
{
int count = 0;
 
*val = 0;
 
while (**s)
{
int hexval = gdb_atoi_hex(**s);
if (hexval < 0)
break;
 
(*s)++;
count++;
 
*val = (*val << 4) | (hexval & 0xF);
}
 
return count;
}
//-----------------------------------------------------------------
// gdb_send: Send GDB formatted packet ($buffer#checksum)
//-----------------------------------------------------------------
static void gdb_send(char *buffer)
{
unsigned char checksum;
int index;
 
do
{
checksum = 0;
index = 0;
 
// Start of packet
gdb_putchar ('$');
 
// Payload (if any)
while (buffer[index] != 0)
{
gdb_putchar(buffer[index]);
checksum += (unsigned char)buffer[index++];
}
 
// Checksum
gdb_putchar('#');
gdb_putchar(_hex_char[(checksum >> 4) & 0xF]);
gdb_putchar(_hex_char[(checksum >> 0) & 0xF]);
}
while (gdb_getchar () != '+');
}
//-----------------------------------------------------------------
// gdb_recv: Wait for valid GDB packet ($cmd#checksum).
// 'cmd' is returned
//-----------------------------------------------------------------
static char * gdb_recv(void)
{
int found_start = 0;
unsigned char checksum;
unsigned char csum_rx;
int index;
char ch;
 
while (1)
{
ch = gdb_getchar();
 
// Start of packet indicator?
if (ch == '$')
{
found_start = 1;
checksum = 0;
csum_rx = 0;
index = 0;
}
// Already received start of packet
else if (found_start)
{
// Found start of checksum
if (ch == '#')
break;
 
if (index < (MAX_BUF_SIZE-1))
_inbuffer[index++] = ch;
 
checksum = checksum + ch;
}
}
_inbuffer[index++] = 0;
// If command received without overflowing buffer
if (index < MAX_BUF_SIZE)
{
// Extract / wait for checksum
ch = gdb_getchar();
csum_rx = gdb_atoi_hex (ch) << 4;
ch = gdb_getchar ();
csum_rx += gdb_atoi_hex (ch);
 
// Valid checksum
if (checksum == csum_rx)
{
// Sequence number?
if (_inbuffer[2] == ':')
{
gdb_putchar('+');
gdb_putchar (_inbuffer[0]);
gdb_putchar (_inbuffer[1]);
 
return &_inbuffer[3];
}
else
{
// Simple Ack
gdb_putchar('+');
 
return &_inbuffer[0];
}
}
else
{
_inbuffer[0] = 0;
 
return &_inbuffer[0];
}
}
else
{
_inbuffer[0] = 0;
 
return &_inbuffer[0];
}
}
//-----------------------------------------------------------------
// gdb_exception
//-----------------------------------------------------------------
unsigned int * gdb_exception(unsigned int *registers, unsigned int reason)
{
int sig_val;
unsigned int len;
unsigned int val;
unsigned int regnum;
char *str;
char *ptr;
int flush_caches = 0;
switch (reason)
{
case OR32_EXC_INT:
sig_val = GDB_SIGINT;
break;
case OR32_EXC_BREAKPOINT:
sig_val = GDB_SIGTRAP;
break;
case OR32_EXC_FAULT:
sig_val = GDB_SIGSEGV;
break;
default:
sig_val = GDB_SIGHUP;
break;
}
 
// Exception due external interrupt
if (reason == OR32_EXC_INT)
{
if (irq_handler)
return irq_handler(registers);
}
// Exception due to syscall instruction
else if (reason == OR32_EXC_SYSCALL)
{
// Get l.sys opcode
unsigned int opcode = *((unsigned int*)(registers[REG_PC] - 4));
unsigned int sys_num = opcode & 0xFFFF;
 
ptr = _outbuffer;
switch (sys_num)
{
//---------------------------------------------------
// l.sys 1 -> putchar(r3)
//---------------------------------------------------
case 1:
*ptr++ = 'O';
*ptr++ = _hex_char[(registers[REG_ARG0] >> 4) & 0xf];
*ptr++ = _hex_char[registers[REG_ARG0] & 0xf];
*ptr++ = 0;
gdb_send (_outbuffer);
 
return registers;
//---------------------------------------------------
// l.sys 2 -> putstr(r3)
//---------------------------------------------------
case 2:
// Pointer to string
str = (char*)registers[REG_ARG0];
len = 0;
 
*ptr++ = 'O';
while (*str && (len < ((sizeof(_outbuffer)-2)/2)))
{
*ptr++ = _hex_char[((*str) >> 4) & 0xf];
*ptr++ = _hex_char[((*str) >> 0) & 0xf];
str++;
}
*ptr++ = 0;
gdb_send (_outbuffer);
 
return registers;
//---------------------------------------------------
// l.sys 3 -> exit(r3)
//---------------------------------------------------
case 3:
*ptr++ = 'W';
*ptr++ = _hex_char[(registers[REG_ARG0] >> 4) & 0xf];
*ptr++ = _hex_char[registers[REG_ARG0] & 0xf];
*ptr++ = 0;
gdb_send (_outbuffer);
 
// Remain in GDB stub...
break;
//---------------------------------------------------
// l.sys 4 -> set syscall_handler = r3
//---------------------------------------------------
case 4:
syscall_handler = (void*)registers[REG_ARG0];
return registers;
//---------------------------------------------------
// l.sys 5 -> set irq_handler = r3
//---------------------------------------------------
case 5:
irq_handler = (void*)registers[REG_ARG0];
return registers;
//---------------------------------------------------
// Default: User syscall
//---------------------------------------------------
default:
if (syscall_handler)
return syscall_handler(registers);
// Not supported
else
{
registers[REG_ARG0] = 0;
return registers;
}
}
}
 
// Make sure debug enabled on return to user program
registers[REG_SR] |= (1 << OR32_SR_DBGEN);
 
// Send status response (signal type, PC & SP)
if (!_initial_trap)
{
ptr = _outbuffer;
*ptr++ = 'T';
*ptr++ = _hex_char[(sig_val >> 4) & 0xf];
*ptr++ = _hex_char[sig_val & 0xf];
*ptr++ = _hex_char[(REG_PC >> 4) & 0xf];
*ptr++ = _hex_char[REG_PC & 0xf];
*ptr++ = ':';
ptr = gdb_mem2hex ((unsigned char *)&registers[REG_PC], ptr, 4);
*ptr++ = ';';
*ptr++ = _hex_char[(REG_SP >> 4) & 0xf];
*ptr++ = _hex_char[REG_SP & 0xf];
*ptr++ = ':';
ptr = gdb_mem2hex ((unsigned char *)&registers[REG_SP], ptr, 4);
*ptr++ = ';';
*ptr++ = 0;
gdb_send (_outbuffer);
}
// Initial trap (jump to GDB stub)
else
{
sig_val = GDB_SIGHUP;
_initial_trap = 0;
}
 
while (1)
{
// Wait for request from GDB
ptr = gdb_recv();
_outbuffer[0] = 0;
switch (*ptr++)
{
//---------------------------------------------------
// ? - Return signal value
//---------------------------------------------------
case '?':
_outbuffer[0] = 'S';
_outbuffer[1] = _hex_char[sig_val >> 4];
_outbuffer[2] = _hex_char[sig_val & 0xf];
_outbuffer[3] = 0;
break;
//---------------------------------------------------
// g - Return all registers
//---------------------------------------------------
case 'g':
ptr = gdb_mem2hex ((unsigned char *)registers, _outbuffer, REG_NUM * 4);
break;
//---------------------------------------------------
// G - Set all registers
//---------------------------------------------------
case 'G':
gdb_hex2mem (ptr, (unsigned char *)registers, REG_NUM * 4);
gdb_strcpy (_outbuffer, "OK");
 
// Make sure debug enabled on return to user program
registers[REG_SR] |= (1 << OR32_SR_DBGEN);
break;
//---------------------------------------------------
// p - Return a single register
//---------------------------------------------------
case 'p':
if (gdb_gethexword (&ptr, &val) && (val < REG_NUM))
ptr = gdb_mem2hex ((unsigned char *)&registers[val], _outbuffer, 4);
else
gdb_strcpy (_outbuffer, "E22");
break;
//---------------------------------------------------
// P - Set a single register
//---------------------------------------------------
case 'P':
// Get register number
if (gdb_gethexword (&ptr, &regnum) && (*ptr++ == '=') && (regnum < REG_NUM))
{
// Get value to set register to
gdb_gethexword(&ptr, &val);
registers[regnum] = val;
 
// If SR, make sure debug enabled on return to user program
if (regnum == REG_SR)
registers[regnum] |= (1 << OR32_SR_DBGEN);
 
gdb_strcpy (_outbuffer, "OK");
}
else
gdb_strcpy (_outbuffer, "E22");
break;
//---------------------------------------------------
// m - Read a block of memory
//---------------------------------------------------
case 'm':
if (gdb_gethexword (&ptr, &val) && (*ptr++ == ',') &&
gdb_gethexword (&ptr, &len) && (len < ((sizeof(_outbuffer)-1)/2)))
{
if (!gdb_mem2hex((unsigned char *)val, _outbuffer, len))
gdb_strcpy (_outbuffer, "E14");
}
else
gdb_strcpy (_outbuffer,"E22");
break;
//---------------------------------------------------
// M - Write a block of memory
//---------------------------------------------------
case 'M':
if (gdb_gethexword (&ptr, &val) && (*ptr++ == ',') &&
gdb_gethexword (&ptr, &len) && (*ptr++ == ':'))
{
if (gdb_hex2mem(ptr, (unsigned char *)val, len))
gdb_strcpy (_outbuffer, "OK");
else
gdb_strcpy (_outbuffer, "E14");
 
flush_caches = 1;
}
else
gdb_strcpy (_outbuffer, "E22");
break;
//---------------------------------------------------
// c - Continue from address (or last PC)
//---------------------------------------------------
case 'c':
// Optional PC
if (gdb_gethexword (&ptr, &val))
registers[REG_PC] = val;
 
if (flush_caches)
gdb_flush_cache();
 
return registers;
//---------------------------------------------------
// s - Step from address (or last PC)
//---------------------------------------------------
case 's':
// Optional PC
if (gdb_gethexword (&ptr, &val))
registers[REG_PC] = val;
 
// Set step in ESR and make sure debug is enabled
registers[REG_SR] |= (1 << OR32_SR_STEP);
registers[REG_SR] |= (1 << OR32_SR_DBGEN);
if (flush_caches)
gdb_flush_cache();
 
return registers;
}
 
// Send response to GDB host
gdb_send (_outbuffer);
}
}
//-----------------------------------------------------------------
// gdb_main
//-----------------------------------------------------------------
void gdb_main(void)
{
gdb_putstr("\r\nGDB Debug Agent\r\n");
 
// Jump to debugger
_initial_trap = 1;
asm volatile ("l.trap 0");
 
while (1)
;
}
/sw/gdb_stub/makefile
0,0 → 1,73
###############################################################################
# Configuration
###############################################################################
# Target
TARGET ?= gdb_stub
 
# Memory Layout
MEMBASE ?= 0x10000000
MEMSIZE ?= 12384
MEMNAME ?= sram
 
###############################################################################
# Files
###############################################################################
INCLUDE_DIRS ?=
OBJ = boot.o
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
OBJ+= $(OBJS)
 
###############################################################################
## Makefile
###############################################################################
 
# Tools
OR1K_TCHAIN ?= or1k-elf
CC = $(OR1K_TCHAIN)-gcc $(CFLAGS)
AS = $(OR1K_TCHAIN)-as
LD = $(OR1K_TCHAIN)-ld
OBJDUMP = $(OR1K_TCHAIN)-objdump
OBJCOPY = $(OR1K_TCHAIN)-objcopy
 
# Options
CFLAGS ?=
CFLAGS += -Ttext $(MEMBASE) -Os -g -Wall
CFLAGS += -msoft-div -msoft-float -msoft-mul -mno-ror -mno-cmov -mno-sext
CFLAGS += -nostartfiles -nodefaultlibs -nostdlib -lgcc -L .
ASFLAGS =
LDFLAGS =
 
LDSCRIPT= linker_script
CFLAGS += -mno-delay -D__OR1K_NODELAY__ -D__OR1K__
ASFLAGS+= -mno-delay -Wa,--defsym,__OR1K_NODELAY__=1
CFLAGS += -T$(LDSCRIPT)
SIMARGS += -n
 
CFLAGS += -I. $(INCLUDE_DIRS)
 
###############################################################################
# Rules
###############################################################################
all: $(TARGET).elf lst bin
clean:
-rm $(OBJ) *.map *.lst *.hex *.txt *.elf $(TARGET).bin
 
%.o : %.s
$(CC) -c $(ASFLAGS) $< -o $@
 
%.o : %.c
$(CC) -c $(CFLAGS) $< -o $@
 
$(TARGET).elf: $(OBJ) $(LDSCRIPT) makefile
$(CC) $(LDFLAGS) $(LIBS) $(OBJ) -o $@
lst: $(TARGET).lst
 
%.lst: $(TARGET).elf
$(OBJDUMP) -h -d -S $< > $@
 
bin: $(TARGET).bin
 
%.bin: %.elf
$(OBJCOPY) -O binary $< $@

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.