| 95 |
theseven |
1 |
//
|
|
|
2 |
//
|
|
|
3 |
// Copyright 2010 TheSeven
|
|
|
4 |
//
|
|
|
5 |
//
|
|
|
6 |
// This file is part of emBIOS.
|
|
|
7 |
//
|
|
|
8 |
// emBIOS is free software: you can redistribute it and/or
|
|
|
9 |
// modify it under the terms of the GNU General Public License as
|
|
|
10 |
// published by the Free Software Foundation, either version 2 of the
|
|
|
11 |
// License, or (at your option) any later version.
|
|
|
12 |
//
|
|
|
13 |
// emBIOS is distributed in the hope that it will be useful,
|
|
|
14 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
15 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
16 |
// See the GNU General Public License for more details.
|
|
|
17 |
//
|
|
|
18 |
// You should have received a copy of the GNU General Public License along
|
|
|
19 |
// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
|
|
20 |
//
|
|
|
21 |
//
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
#include "global.h"
|
|
|
25 |
#include "bootflash.h"
|
|
|
26 |
#include "contextswitch.h"
|
|
|
27 |
#include "util.h"
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
#define nor ((uint8_t*)0x24000000)
|
|
|
31 |
#define norword ((uint32_t*)0x24000000)
|
|
|
32 |
#define norflsh ((volatile uint16_t*)0x24000000)
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
extern void control_nor_cache(bool enable);
|
|
|
36 |
|
|
|
37 |
|
|
|
38 |
static void* findflashfile(const char* filename, uint32_t* size)
|
|
|
39 |
{
|
|
|
40 |
uint32_t i;
|
|
|
41 |
for (i = 0; i < 0x1000; i += 0x10)
|
|
|
42 |
if (memcmp(&nor[i], filename, 8) == 0)
|
|
|
43 |
{
|
|
|
44 |
*size = norword[(i + 0xc) >> 2];
|
|
|
45 |
return &nor[norword[(i + 0x8) >> 2]];
|
|
|
46 |
}
|
|
|
47 |
return 0;
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
int bootflash_filesize(const char* filename)
|
|
|
51 |
{
|
|
|
52 |
uint32_t size;
|
|
|
53 |
if (findflashfile(filename, &size)) return size & 0xfffff;
|
|
|
54 |
else return -1;
|
|
|
55 |
}
|
|
|
56 |
|
|
|
57 |
int bootflash_attributes(const char* filename)
|
|
|
58 |
{
|
|
|
59 |
uint32_t size;
|
|
|
60 |
if (findflashfile(filename, &size)) return size >> 20;
|
|
|
61 |
else return -1;
|
|
|
62 |
}
|
|
|
63 |
|
|
|
64 |
void* bootflash_getaddr(const char* filename)
|
|
|
65 |
{
|
|
|
66 |
uint32_t size;
|
|
|
67 |
return findflashfile(filename, &size);
|
|
|
68 |
}
|
|
|
69 |
|
|
|
70 |
int bootflash_read(const char* filename, void* addr, int offset, int size)
|
|
|
71 |
{
|
|
|
72 |
uint32_t fsize;
|
|
|
73 |
uint8_t* file = (uint8_t*)findflashfile(filename, &fsize);
|
|
|
74 |
if (!file) return -1;
|
|
|
75 |
fsize &= 0xfffff;
|
|
|
76 |
if (offset + size > fsize) size = fsize - offset;
|
|
|
77 |
if (size > 0) memcpy(addr, &file[offset], size);
|
|
|
78 |
return size;
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
void bootflash_readraw(void* addr, int offset, int size)
|
|
|
82 |
{
|
|
|
83 |
memcpy(addr, &nor[offset], size);
|
|
|
84 |
}
|
|
|
85 |
|
|
|
86 |
void bootflash_writeraw(void* addr, int offset, int size)
|
|
|
87 |
{
|
|
|
88 |
uint32_t mode = enter_critical_section();
|
|
|
89 |
control_nor_cache(false);
|
|
|
90 |
|
|
|
91 |
while (size > 0)
|
|
|
92 |
{
|
|
|
93 |
int remainder = MIN(0x1000 - (offset & 0xfff), size);
|
|
|
94 |
if (memcmp(&nor[offset], addr, remainder))
|
|
|
95 |
{
|
|
|
96 |
bool needserase = false;
|
|
|
97 |
int i;
|
|
|
98 |
for (i = 0; i < remainder; i += 2)
|
|
|
99 |
if (norflsh[(offset + i) >> 1] != 0xffff)
|
|
|
100 |
needserase = true;
|
|
|
101 |
if (needserase)
|
|
|
102 |
{
|
|
|
103 |
norflsh[0x5555] = 0xaa;
|
|
|
104 |
norflsh[0x2aaa] = 0x55;
|
|
|
105 |
norflsh[0x5555] = 0x80;
|
|
|
106 |
norflsh[0x5555] = 0xaa;
|
|
|
107 |
norflsh[0x2aaa] = 0x55;
|
|
|
108 |
norflsh[(offset & ~0xfff) >> 1] = 0x30;
|
|
|
109 |
while (norflsh[(offset & ~0xfff) >> 1] != 0xffff);
|
|
|
110 |
}
|
| 154 |
theseven |
111 |
for (i = 0; i < remainder; i += 2)
|
|
|
112 |
if (norflsh[(offset + i) >> 1] != ((uint16_t*)addr)[i >> 1])
|
|
|
113 |
{
|
|
|
114 |
norflsh[0x5555] = 0xaa;
|
|
|
115 |
norflsh[0x2aaa] = 0x55;
|
|
|
116 |
norflsh[0x5555] = 0xa0;
|
|
|
117 |
norflsh[(offset + i) >> 1] = ((uint16_t*)addr)[i >> 1];
|
|
|
118 |
while (norflsh[(offset + i) >> 1] != ((uint16_t*)addr)[i >> 1]);
|
|
|
119 |
}
|
| 95 |
theseven |
120 |
}
|
|
|
121 |
addr = (void*)(((uint32_t)addr) + remainder);
|
|
|
122 |
offset += remainder;
|
|
|
123 |
size -= remainder;
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
control_nor_cache(true);
|
|
|
127 |
leave_critical_section(mode);
|
|
|
128 |
}
|
|
|
129 |
|
|
|
130 |
void* bootflash_getrawaddr(int offset)
|
|
|
131 |
{
|
|
|
132 |
return &nor[offset];
|
|
|
133 |
}
|
| 138 |
theseven |
134 |
|
|
|
135 |
bool bootflash_is_memmapped()
|
|
|
136 |
{
|
|
|
137 |
#ifdef BOOTFLASH_IS_MEMMAPPED
|
|
|
138 |
return true;
|
|
|
139 |
#else
|
|
|
140 |
return false;
|
|
|
141 |
#endif
|
|
|
142 |
}
|