Commits

dtrg  committed acb1567

Add special relocation type for VC4 jump instructions.

  • Participants
  • Parent commits de76880
  • Branches dtrg-videocore

Comments (0)

Files changed (4)

 #define RELO4	   3			/* 4 bytes */
 #define RELOPPC    4            /* PowerPC 26-bit address */
 #define RELOH2     5            /* write top 2 bytes of 4 byte word */
+#define RELOVC4    6            /* VideoCore IV address in 32-bit instruction */
 
 #define RELPC	0x08			/* pc relative */
 #define RELBR	0x10			/* High order byte lowest address. */

File util/amisc/ashow.c

 	case RELOH2:
 		printf("\ttop 2 bytes of a 4 byte word\n");
 		break;
+	case RELOVC4:
+		printf("\tVideoCore IV address in 32-bit instruction\n");
+		break;
 	default:
 		printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
 		break;

File util/led/ack.out.5

 #define RELO4	0x03		/* 4 bytes */
 #define RELOPPC	0x04		/* 26-bit PowerPC address */
 #define RELOH2  0x05        /* write top 2 bytes of 4 byte word */
+#define RELOVC4 0x06        /* VideoCore IV address in 32-bit insruction */
 #define RELPC	0x08		/* pc relative */
 #define RELBR	0x10		/* High order byte lowest address. */
 #define RELWR	0x20		/* High order word lowest address. */

File util/led/relocate.c

 
 #include <stdlib.h>
 #include <stdio.h>
+#include <assert.h>
 #include "out.h"
 #include "const.h"
 #include "debug.h"
 		return read4(addr, type) & 0x03FFFFFD;
 	case RELOH2:
 		return read2(addr, type) << 16;
+	case RELOVC4:
+	{
+		long i = read4(addr, type);
+		if (i & 0x00800000)
+		{
+            /* Branch instruction. */
+            return (i<<9)>>9;
+		}
+		else
+		{
+			/* Branch-link instruction. */
+			long hi = (i<<4)>>28;
+			long lo = (i & 0x007fffff);
+			return lo | (hi<<23);
+		}
+	}
 	default:
 		fatal("bad relocation size");
 	}
 	case RELOH2:
 		write2(valu>>16, addr, type);
 		break;
+	case RELOVC4:
+	{
+		long i = read4(addr, type);
+		if (i & 0x00800000)
+		{
+			/* Branch instruction. */
+			unsigned v = (valu/2) & 0x007fffff;
+			i &= ~0x007fffff;
+			i |= v;
+		}
+		else
+		{
+			/* Branch-link instruction. */
+	        unsigned v = (valu/2) & 0x07ffffff;
+	        unsigned hiv = v >> 23;
+	        unsigned lov = v & 0x007fffff;
+			i &= ~0x0f7fffff;
+			i |= (lov>>16) | (hiv<<24);
+		}
+		write4(i, addr, type);
+		break;
+	}
 	default:
 		fatal("bad relocation size");
 	}