Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / resource.c
1 #include <lwk/kernel.h>
2 #include <lwk/init.h>
3 #include <lwk/resource.h>
4 #include <arch/page.h>
5 #include <arch/io.h>
6 #include <arch/sections.h>
7 #include <arch/e820.h>
8
9 /**
10  * Standard PC resources.
11  */
12 struct resource standard_io_resources[] = {
13         { .name = "dma1", .start = 0x00, .end = 0x1f,
14                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
15         { .name = "pic1", .start = 0x20, .end = 0x21,
16                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
17         { .name = "timer0", .start = 0x40, .end = 0x43,
18                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
19         { .name = "timer1", .start = 0x50, .end = 0x53,
20                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
21         { .name = "keyboard", .start = 0x60, .end = 0x6f,
22                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
23         { .name = "dma page reg", .start = 0x80, .end = 0x8f,
24                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
25         { .name = "pic2", .start = 0xa0, .end = 0xa1,
26                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
27         { .name = "dma2", .start = 0xc0, .end = 0xdf,
28                 .flags = IORESOURCE_BUSY | IORESOURCE_IO },
29         { .name = "fpu", .start = 0xf0, .end = 0xff,
30                 .flags = IORESOURCE_BUSY | IORESOURCE_IO }
31 };
32
33 #define STANDARD_IO_RESOURCES \
34         (sizeof standard_io_resources / sizeof standard_io_resources[0])
35
36 #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
37
38 struct resource data_resource = {
39         .name = "Kernel data",
40         .start = 0,
41         .end = 0,
42         .flags = IORESOURCE_RAM,
43 };
44 struct resource code_resource = {
45         .name = "Kernel code",
46         .start = 0,
47         .end = 0,
48         .flags = IORESOURCE_RAM,
49 };
50
51 #define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
52
53 static struct resource system_rom_resource = {
54         .name = "System ROM",
55         .start = 0xf0000,
56         .end = 0xfffff,
57         .flags = IORESOURCE_ROM,
58 };
59
60 static struct resource extension_rom_resource = {
61         .name = "Extension ROM",
62         .start = 0xe0000,
63         .end = 0xeffff,
64         .flags = IORESOURCE_ROM,
65 };
66
67 static struct resource adapter_rom_resources[] = {
68         { .name = "Adapter ROM", .start = 0xc8000, .end = 0,
69                 .flags = IORESOURCE_ROM },
70         { .name = "Adapter ROM", .start = 0, .end = 0,
71                 .flags = IORESOURCE_ROM },
72         { .name = "Adapter ROM", .start = 0, .end = 0,
73                 .flags = IORESOURCE_ROM },
74         { .name = "Adapter ROM", .start = 0, .end = 0,
75                 .flags = IORESOURCE_ROM },
76         { .name = "Adapter ROM", .start = 0, .end = 0,
77                 .flags = IORESOURCE_ROM },
78         { .name = "Adapter ROM", .start = 0, .end = 0,
79                 .flags = IORESOURCE_ROM }
80 };
81
82 #define ADAPTER_ROM_RESOURCES \
83         (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
84
85 static struct resource video_rom_resource = {
86         .name = "Video ROM",
87         .start = 0xc0000,
88         .end = 0xc7fff,
89         .flags = IORESOURCE_ROM,
90 };
91
92 static struct resource video_ram_resource = {
93         .name = "Video RAM area",
94         .start = 0xa0000,
95         .end = 0xbffff,
96         .flags = IORESOURCE_RAM,
97 };
98
99 #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
100
101 static int __init
102 romchecksum(unsigned char *rom, unsigned long length)
103 {
104         unsigned char *p, sum = 0;
105
106         for (p = rom; p < rom + length; p++)
107                 sum += *p;
108         return sum == 0;
109 }
110
111 static void __init
112 probe_roms(void)
113 {
114         unsigned long start, length, upper;
115         unsigned char *rom;
116         int           i;
117
118         /* video rom */
119         upper = adapter_rom_resources[0].start;
120         for (start = video_rom_resource.start; start < upper; start += 2048) {
121                 rom = isa_bus_to_virt(start);
122                 if (!romsignature(rom))
123                         continue;
124
125                 video_rom_resource.start = start;
126
127                 /* 0 < length <= 0x7f * 512, historically */
128                 length = rom[2] * 512;
129
130                 /* if checksum okay, trust length byte */
131                 if (length && romchecksum(rom, length))
132                         video_rom_resource.end = start + length - 1;
133
134                 request_resource(&iomem_resource, &video_rom_resource);
135                 break;
136         }
137
138         start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
139         if (start < upper)
140                 start = upper;
141
142         /* system rom */
143         request_resource(&iomem_resource, &system_rom_resource);
144         upper = system_rom_resource.start;
145
146         /* check for extension rom (ignore length byte!) */
147         rom = isa_bus_to_virt(extension_rom_resource.start);
148         if (romsignature(rom)) {
149                 length = extension_rom_resource.end - extension_rom_resource.start + 1;
150                 if (romchecksum(rom, length)) {
151                         request_resource(&iomem_resource, &extension_rom_resource);
152                         upper = extension_rom_resource.start;
153                 }
154         }
155
156         /* check for adapter roms on 2k boundaries */
157         for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
158                 rom = isa_bus_to_virt(start);
159                 if (!romsignature(rom))
160                         continue;
161
162                 /* 0 < length <= 0x7f * 512, historically */
163                 length = rom[2] * 512;
164
165                 /* but accept any length that fits if checksum okay */
166                 if (!length || start + length > upper || !romchecksum(rom, length))
167                         continue;
168
169                 adapter_rom_resources[i].start = start;
170                 adapter_rom_resources[i].end = start + length - 1;
171                 request_resource(&iomem_resource, &adapter_rom_resources[i]);
172
173                 start = adapter_rom_resources[i++].end & ~2047UL;
174         }
175 }
176
177 void __init
178 init_resources(void)
179 {
180         unsigned int i;
181
182         code_resource.start = virt_to_phys(&_text);
183         code_resource.end   = virt_to_phys(&_etext)-1;
184         data_resource.start = virt_to_phys(&_etext);
185         data_resource.end   = virt_to_phys(&_edata)-1;
186
187         /*
188          * Request address space for all standard RAM and ROM resources
189          * and also for regions reported as reserved by the e820.
190          */
191         probe_roms();
192         e820_reserve_resources(); 
193
194         request_resource(&iomem_resource, &video_ram_resource);
195
196         /* request I/O space for devices used on all i[345]86 PCs */
197         for (i = 0; i < STANDARD_IO_RESOURCES; i++)
198                 request_resource(&ioport_resource, &standard_io_resources[i]);
199 }
200