|
1 /* |
|
2 * Syborg platform device |
|
3 * |
|
4 * Copyright (c) 2008 CodeSourcery |
|
5 * |
|
6 * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 * of this software and associated documentation files (the "Software"), to deal |
|
8 * in the Software without restriction, including without limitation the rights |
|
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 * copies of the Software, and to permit persons to whom the Software is |
|
11 * furnished to do so, subject to the following conditions: |
|
12 * |
|
13 * The above copyright notice and this permission notice shall be included in |
|
14 * all copies or substantial portions of the Software. |
|
15 * |
|
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
22 * THE SOFTWARE. |
|
23 */ |
|
24 |
|
25 #include "hw.h" |
|
26 #include "syborg.h" |
|
27 #include "devtree.h" |
|
28 |
|
29 //#define DEBUG_SYBORG_PLATFORM |
|
30 |
|
31 #ifdef DEBUG_SYBORG_PLATFORM |
|
32 #define DPRINTF(fmt, args...) \ |
|
33 do { printf("syborg_platform: " fmt , ##args); } while (0) |
|
34 #define BADF(fmt, args...) \ |
|
35 do { fprintf(stderr, "syborg_platform: error: " fmt , ##args); exit(1);} while (0) |
|
36 #else |
|
37 #define DPRINTF(fmt, args...) do {} while(0) |
|
38 #define BADF(fmt, args...) \ |
|
39 do { fprintf(stderr, "syborg_platform: error: " fmt , ##args);} while (0) |
|
40 #endif |
|
41 |
|
42 enum { |
|
43 PLATFORM_ID = 0, |
|
44 PLATFORM_TREE_START = 1 |
|
45 }; |
|
46 |
|
47 #define PLATFORM_TREE_OFFSET 0x1000 |
|
48 |
|
49 typedef struct { |
|
50 QEMUDevice *qdev; |
|
51 } syborg_platform_state; |
|
52 |
|
53 static uint32_t syborg_platform_readl(void *opaque, target_phys_addr_t offset) |
|
54 { |
|
55 offset &= 0xffffff; |
|
56 if (offset >= PLATFORM_TREE_OFFSET) { |
|
57 offset -= PLATFORM_TREE_OFFSET; |
|
58 if (offset >= machine_devtree_size) |
|
59 return 0; |
|
60 return ldl_p((char *)machine_devtree + offset); |
|
61 } |
|
62 DPRINTF("read 0x%x\n", (int)offset); |
|
63 switch(offset >> 2) { |
|
64 case PLATFORM_ID: |
|
65 return SYBORG_ID_PLATFORM; |
|
66 case PLATFORM_TREE_START: |
|
67 return PLATFORM_TREE_OFFSET; |
|
68 default: |
|
69 cpu_abort(cpu_single_env, "syborg_platform_read: Bad offset %x\n", |
|
70 (int)offset); |
|
71 return 0; |
|
72 } |
|
73 } |
|
74 |
|
75 static uint32_t syborg_platform_readw(void *opaque, target_phys_addr_t offset) |
|
76 { |
|
77 offset &= 0xffffff; |
|
78 if (offset >= PLATFORM_TREE_OFFSET) { |
|
79 offset -= PLATFORM_TREE_OFFSET; |
|
80 if (offset >= machine_devtree_size) |
|
81 return 0; |
|
82 return lduw_p((char *)machine_devtree + offset); |
|
83 } |
|
84 cpu_abort(cpu_single_env, "syborg_platform_readw: Bad offset %x\n", |
|
85 (int)offset); |
|
86 } |
|
87 |
|
88 static uint32_t syborg_platform_readb(void *opaque, target_phys_addr_t offset) |
|
89 { |
|
90 offset &= 0xffffff; |
|
91 if (offset >= PLATFORM_TREE_OFFSET) { |
|
92 offset -= PLATFORM_TREE_OFFSET; |
|
93 if (offset >= machine_devtree_size) |
|
94 return 0; |
|
95 return ldub_p((char *)machine_devtree + offset); |
|
96 } |
|
97 cpu_abort(cpu_single_env, "syborg_platform_readb: Bad offset %x\n", |
|
98 (int)offset); |
|
99 } |
|
100 |
|
101 static void syborg_platform_write(void *opaque, target_phys_addr_t offset, |
|
102 uint32_t value) |
|
103 { |
|
104 offset &= 0xffffff; |
|
105 cpu_abort(cpu_single_env, "syborg_platform_write: Bad offset %x\n", |
|
106 (int)offset); |
|
107 } |
|
108 |
|
109 static CPUReadMemoryFunc *syborg_platform_readfn[] = { |
|
110 syborg_platform_readb, |
|
111 syborg_platform_readw, |
|
112 syborg_platform_readl |
|
113 }; |
|
114 |
|
115 static CPUWriteMemoryFunc *syborg_platform_writefn[] = { |
|
116 syborg_platform_write, |
|
117 syborg_platform_write, |
|
118 syborg_platform_write |
|
119 }; |
|
120 |
|
121 static void syborg_platform_create(QEMUDevice *dev) |
|
122 { |
|
123 syborg_platform_state *s; |
|
124 s = (syborg_platform_state *)qemu_mallocz(sizeof(syborg_platform_state)); |
|
125 s->qdev = dev; |
|
126 qdev_set_opaque(dev, s); |
|
127 /* Device has no state, so savevm not needed. */ |
|
128 } |
|
129 |
|
130 void syborg_platform_register(void) |
|
131 { |
|
132 QEMUDeviceClass *dc; |
|
133 dc = qdev_new("syborg,platform", syborg_platform_create, 0); |
|
134 qdev_add_registers(dc, syborg_platform_readfn, syborg_platform_writefn, |
|
135 0x1000000); |
|
136 } |