Blame view

tools/updater/utils.c 2.96 KB
c7de829c7   wdenk   * Patch by Thomas...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  #include <common.h>
  #include <asm/processor.h>
  #include <memio.h>
  #include <linux/ctype.h>
  
  static __inline__ unsigned long
  get_msr(void)
  {
  	unsigned long msr;
  
  	asm volatile("mfmsr %0" : "=r" (msr) :);
  	return msr;
  }
  
  static __inline__ void
  set_msr(unsigned long msr)
  {
8bde7f776   wdenk   * Code cleanup:
18
  	asm volatile("mtmsr %0" : : "r" (msr));
c7de829c7   wdenk   * Patch by Thomas...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  }
  
  static __inline__ unsigned long
  get_dec(void)
  {
  	unsigned long val;
  
  	asm volatile("mfdec %0" : "=r" (val) :);
  	return val;
  }
  
  
  static __inline__ void
  set_dec(unsigned long val)
  {
8bde7f776   wdenk   * Code cleanup:
34
  	asm volatile("mtdec %0" : : "r" (val));
c7de829c7   wdenk   * Patch by Thomas...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  }
  
  
  void
  enable_interrupts(void)
  {
      set_msr (get_msr() | MSR_EE);
  }
  
  /* returns flag if MSR_EE was set before */
  int
  disable_interrupts(void)
  {
      ulong msr;
  
      msr = get_msr();
      set_msr (msr & ~MSR_EE);
      return ((msr & MSR_EE) != 0);
  }
  
  u8 in8(u32 port)
  {
      return in_byte(port);
  }
  
  void out8(u32 port, u8 val)
  {
      out_byte(port, val);
  }
  
  unsigned long in32(u32 port)
  {
      return in_long(port);
  }
  
  unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
  {
8bde7f776   wdenk   * Code cleanup:
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  	unsigned long result = 0,value;
  
  	if (*cp == '0') {
  		cp++;
  		if ((*cp == 'x') && isxdigit(cp[1])) {
  			base = 16;
  			cp++;
  		}
  		if (!base) {
  			base = 8;
  		}
  	}
  	if (!base) {
  		base = 10;
  	}
  	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
  	    ? toupper(*cp) : *cp)-'A'+10) < base) {
  		result = result*base + value;
  		cp++;
  	}
  	if (endp)
  		*endp = (char *)cp;
  	return result;
c7de829c7   wdenk   * Patch by Thomas...
95
96
97
98
  }
  
  long simple_strtol(const char *cp,char **endp,unsigned int base)
  {
8bde7f776   wdenk   * Code cleanup:
99
100
101
  	if(*cp=='-')
  		return -simple_strtoul(cp+1,endp,base);
  	return simple_strtoul(cp,endp,base);
c7de829c7   wdenk   * Patch by Thomas...
102
103
104
105
106
  }
  
  static inline void
  soft_restart(unsigned long addr)
  {
8bde7f776   wdenk   * Code cleanup:
107
108
  	/* SRR0 has system reset vector, SRR1 has default MSR value */
  	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
c7de829c7   wdenk   * Patch by Thomas...
109

8bde7f776   wdenk   * Code cleanup:
110
111
112
113
  	__asm__ __volatile__ ("mtspr    26, %0"         :: "r" (addr));
  	__asm__ __volatile__ ("li       4, (1 << 6)"    ::: "r4");
  	__asm__ __volatile__ ("mtspr    27, 4");
  	__asm__ __volatile__ ("rfi");
c7de829c7   wdenk   * Patch by Thomas...
114

8bde7f776   wdenk   * Code cleanup:
115
  	while(1);       /* not reached */
c7de829c7   wdenk   * Patch by Thomas...
116
117
118
119
120
  }
  
  void
  do_reset (void)
  {
8bde7f776   wdenk   * Code cleanup:
121
122
123
124
125
126
127
128
129
130
131
132
133
  	ulong addr;
  	/* flush and disable I/D cache */
  	__asm__ __volatile__ ("mfspr    3, 1008"        ::: "r3");
  	__asm__ __volatile__ ("ori      5, 5, 0xcc00"   ::: "r5");
  	__asm__ __volatile__ ("ori      4, 3, 0xc00"    ::: "r4");
  	__asm__ __volatile__ ("andc     5, 3, 5"        ::: "r5");
  	__asm__ __volatile__ ("sync");
  	__asm__ __volatile__ ("mtspr    1008, 4");
  	__asm__ __volatile__ ("isync");
  	__asm__ __volatile__ ("sync");
  	__asm__ __volatile__ ("mtspr    1008, 5");
  	__asm__ __volatile__ ("isync");
  	__asm__ __volatile__ ("sync");
c7de829c7   wdenk   * Patch by Thomas...
134

6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
135
136
  #ifdef CONFIG_SYS_RESET_ADDRESS
  	addr = CONFIG_SYS_RESET_ADDRESS;
c7de829c7   wdenk   * Patch by Thomas...
137
  #else
8bde7f776   wdenk   * Code cleanup:
138
  	/*
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
139
140
  	 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
  	 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
8bde7f776   wdenk   * Code cleanup:
141
  	 * address. Better pick an address known to be invalid on your
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
142
  	 * system and assign it to CONFIG_SYS_RESET_ADDRESS.
8bde7f776   wdenk   * Code cleanup:
143
  	 */
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
144
  	addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong);
c7de829c7   wdenk   * Patch by Thomas...
145
  #endif
8bde7f776   wdenk   * Code cleanup:
146
147
  	soft_restart(addr);
  	while(1);       /* not reached */
c7de829c7   wdenk   * Patch by Thomas...
148
  }