"eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp",
"cs", "ds", "es", "fs", "gs", "ss",
"cr0", "cr1", "cr2", "cr3", "cr4",
+ "dr0", "dr1", "dr2", "dr3", "dr6", "dr7",
"st",
};
int reg;
-/* asmconv 1.11 - convert 80X86 assembly Author: Kees J. Bot
+/* asmconv 1.12 - convert 80X86 assembly Author: Kees J. Bot
* 24 Dec 1993
*/
-static char version[] = "1.11";
+static char version[] = "1.12";
#define nil 0
#include <stdio.h>
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello
+20100318:
+ Gas2ack updates: Run 'make install' in commands/i386/gas2ack
# by an upper level Makefile.
OBJS= arch_do_vmctl.o \
+ breakpoints.o \
clock.o \
+ debugreg.o \
do_int86.o \
do_iopenable.o \
do_readbios.o \
gas2ack -u $@.tmp $@.s
$(CC) $(CFLAGS) -c -o $@ $@.s
+debugreg.o: debugreg.S
+ $(CC) $(CFLAGS) -E -D__ASSEMBLY__ -o $@.tmp $<
+ gas2ack -u $@.tmp $@.s
+ $(CC) $(CFLAGS) -c -o $@ $@.s
+
$(HEAD): mpx386.o
cp $< $@
--- /dev/null
+#include "../../kernel.h"
+#include "proto.h"
+
+#include "debugreg.h"
+
+int breakpoint_set(phys_bytes linaddr, int bp, int flags)
+{
+ u32_t dr7, dr7flags;
+
+ if (bp >= BREAKPOINT_COUNT)
+ return EINVAL;
+
+ /* convert flags */
+ dr7flags = 0;
+ switch (flags & BREAKPOINT_FLAG_RW_MASK) {
+ case BREAKPOINT_FLAG_RW_EXEC: dr7flags |= DR7_RW_EXEC(bp); break;
+ case BREAKPOINT_FLAG_RW_WRITE: dr7flags |= DR7_RW_WRITE(bp); break;
+ case BREAKPOINT_FLAG_RW_RW: dr7flags |= DR7_RW_RW(bp); break;
+ default: return EINVAL;
+ }
+ switch (flags & BREAKPOINT_FLAG_LEN_MASK) {
+ case BREAKPOINT_FLAG_LEN_1: dr7flags |= DR7_LN_1(bp); break;
+ case BREAKPOINT_FLAG_LEN_2: dr7flags |= DR7_LN_2(bp); break;
+ case BREAKPOINT_FLAG_LEN_4: dr7flags |= DR7_LN_4(bp); break;
+ default: return EINVAL;
+ }
+ switch (flags & BREAKPOINT_FLAG_MODE_MASK) {
+ case BREAKPOINT_FLAG_MODE_OFF: break;
+ case BREAKPOINT_FLAG_MODE_LOCAL: dr7flags |= DR7_L(bp); break;
+ case BREAKPOINT_FLAG_MODE_GLOBAL: dr7flags |= DR7_G(bp); break;
+ default: return EINVAL;
+ }
+
+ /* disable breakpoint before setting address */
+ dr7 = st_dr7();
+ dr7 &= ~(DR7_L(bp) | DR7_G(bp) | DR7_RW_MASK(bp) | DR7_LN_MASK(bp));
+printf("ld_dr7(0x%x)\n",dr7);
+ ld_dr7(dr7);
+
+ /* need to set new breakpoint? */
+ if ((flags & BREAKPOINT_FLAG_MODE_MASK) == BREAKPOINT_FLAG_MODE_OFF)
+ return 0;
+
+ /* set breakpoint address */
+ switch (bp) {
+ case 0: ld_dr0(linaddr); break;
+ case 1: ld_dr1(linaddr); break;
+ case 2: ld_dr2(linaddr); break;
+ case 3: ld_dr3(linaddr); break;
+ default: panic(__FILE__, "invalid breakpoint index", __LINE__);
+ }
+printf("ld_dr%d(0x%x, 0x%x)\n",bp,linaddr);
+
+ /* set new flags */
+ dr7 |= dr7flags;
+ ld_dr7(dr7);
+printf("ld_dr7(0x%x)\n",dr7);
+ return 0;
+}
+
--- /dev/null
+.text
+
+#define LD_ST_REG(reg) ;\
+.globl ld_##reg ;\
+.globl st_##reg ;\
+ ;\
+ld_##reg: ;\
+ mov 4(%esp), %eax ;\
+ mov %eax, %reg ;\
+ ret ;\
+ ;\
+st_##reg: ;\
+ mov %reg, %eax ;\
+ ret
+
+/*
+ * void ld_dr0(u32_t value)
+ * u32_t st_dr0(void)
+ */
+LD_ST_REG(dr0)
+LD_ST_REG(dr1)
+LD_ST_REG(dr2)
+LD_ST_REG(dr3)
+LD_ST_REG(dr6)
+LD_ST_REG(dr7)
+
--- /dev/null
+#ifndef __DEBUGREG_H__
+#define __DEBUGREG_H__
+
+/* DR6: status flags */
+#define DR6_B(bp) (1 << (bp)) /* breakpoint was triggered */
+#define DR6_BD (1 << 13) /* debug register access detected */
+#define DR6_BS (1 << 14) /* single step */
+#define DR6_BT (1 << 15) /* task switch */
+
+/* DR7: control flags */
+#define DR7_L(bp) (1 << (2*(bp))) /* breakpoint armed locally */
+#define DR7_G(bp) (1 << (1+2*(bp))) /* breakpoint armed globally */
+#define DR7_LE (1 << 8) /* exact local breakpoints */
+#define DR7_GE (1 << 9) /* exact global breakpoints */
+#define DR7_GD (1 << 13) /* detect debug reg movs */
+
+#define DR7_RW_MASK(bp) (3 << (16+4*(bp)))
+#define DR7_RW_EXEC(bp) (0 << (16+4*(bp))) /* execute */
+#define DR7_RW_WRITE(bp) (1 << (16+4*(bp))) /* write */
+#define DR7_RW_IO(bp) (2 << (16+4*(bp))) /* IO */
+#define DR7_RW_RW(bp) (3 << (16+4*(bp))) /* read or write */
+
+#define DR7_LN_MASK(bp) (3 << (18+4*(bp)))
+#define DR7_LN_1(bp) (0 << (18+4*(bp))) /* 1 byte */
+#define DR7_LN_2(bp) (1 << (18+4*(bp))) /* 2 bytes */
+#define DR7_LN_8(bp) (2 << (18+4*(bp))) /* 8 bytes */
+#define DR7_LN_4(bp) (3 << (18+4*(bp))) /* 4 bytes */
+
+/* debugreg.S */
+void ld_dr0(u32_t value);
+void ld_dr1(u32_t value);
+void ld_dr2(u32_t value);
+void ld_dr3(u32_t value);
+void ld_dr6(u32_t value);
+void ld_dr7(u32_t value);
+u32_t st_dr0(void);
+u32_t st_dr1(void);
+u32_t st_dr2(void);
+u32_t st_dr3(void);
+u32_t st_dr6(void);
+u32_t st_dr7(void);
+
+#endif /* __DEBUGREG_H__ */
+
_PROTOTYPE(void __copy_msg_to_user_end, (void));
_PROTOTYPE(void __user_copy_msg_pointer_failure, (void));
+/* breakpoints.c */
+#define BREAKPOINT_COUNT 4
+#define BREAKPOINT_FLAG_RW_MASK (3 << 0)
+#define BREAKPOINT_FLAG_RW_EXEC (0 << 0)
+#define BREAKPOINT_FLAG_RW_WRITE (1 << 0)
+#define BREAKPOINT_FLAG_RW_RW (2 << 0)
+#define BREAKPOINT_FLAG_LEN_MASK (3 << 2)
+#define BREAKPOINT_FLAG_LEN_1 (0 << 2)
+#define BREAKPOINT_FLAG_LEN_2 (1 << 2)
+#define BREAKPOINT_FLAG_LEN_4 (2 << 2)
+#define BREAKPOINT_FLAG_MODE_MASK (3 << 4)
+#define BREAKPOINT_FLAG_MODE_OFF (0 << 4)
+#define BREAKPOINT_FLAG_MODE_LOCAL (1 << 4)
+#define BREAKPOINT_FLAG_MODE_GLOBAL (2 << 4)
+
+_PROTOTYPE(int breakpoint_set, (phys_bytes linaddr, int index, int flags));
+
/* functions defined in architecture-independent kernel source. */
#include "../../proto.h"