* [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu.
@ 2008-08-27 13:45 Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-08-27 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
bswap.h | 29 +++++++++++
hw/usb-net.c | 158 +++++++++++++++++++++++++++++----------------------------
2 files changed, 109 insertions(+), 78 deletions(-)
diff --git a/bswap.h b/bswap.h
index 523d805..feb2d6b 100644
--- a/bswap.h
+++ b/bswap.h
@@ -206,4 +206,33 @@ static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
#undef le_bswaps
#undef be_bswaps
+/* byteordered types and accessors */
+
+typedef struct { uint16_t le; } le16 __attribute__((__aligned__(2)));
+typedef struct { uint32_t le; } le32;
+typedef struct { uint64_t le; } le64;
+typedef struct { uint16_t be; } be16 __attribute__((__aligned__(2)));
+typedef struct { uint32_t be; } be32;
+typedef struct { uint64_t be; } be64;
+
+static inline uint16_t read_le16(le16 le) { return le16_to_cpu(le.le); }
+static inline uint32_t read_le32(le32 le) { return le32_to_cpu(le.le); }
+static inline uint64_t read_le64(le64 le) { return le64_to_cpu(le.le); }
+static inline uint16_t read_be16(be16 be) { return be16_to_cpu(be.be); }
+static inline uint32_t read_be32(be32 be) { return be32_to_cpu(be.be); }
+static inline uint64_t read_be64(be64 be) { return be64_to_cpu(be.be); }
+
+static inline le16 write_le16(uint16_t cpu) \
+ { le16 ret = { .le = cpu_to_le16(cpu) }; return ret; }
+static inline le32 write_le32(uint32_t cpu) \
+ { le32 ret = { .le = cpu_to_le32(cpu) }; return ret; }
+static inline le64 write_le64(uint64_t cpu) \
+ { le64 ret = { .le = cpu_to_le64(cpu) }; return ret; }
+static inline be16 write_be16(uint16_t cpu) \
+ { be16 ret = { .be = cpu_to_be16(cpu) }; return ret; }
+static inline be32 write_be32(uint32_t cpu) \
+ { be32 ret = { .be = cpu_to_be32(cpu) }; return ret; }
+static inline be64 write_be64(uint64_t cpu) \
+ { be64 ret = { .be = cpu_to_be64(cpu) }; return ret; }
+
#endif /* BSWAP_H */
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 27dea10..dbeb54a 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -326,8 +326,6 @@ enum {
#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xfd010104
#define OID_PNP_ENABLE_WAKE_UP 0xfd010106
-typedef uint32_t le32;
-
typedef struct rndis_init_msg_type {
le32 MessageType;
le32 MessageLength;
@@ -629,6 +627,7 @@ static int ndis_query(USBNetState *s, uint32_t oid,
size_t outlen)
{
unsigned int i, count;
+ le32 *outbuf32 = (void*)outbuf;
switch (oid) {
/* general oids (table 4-1) */
@@ -636,47 +635,47 @@ static int ndis_query(USBNetState *s, uint32_t oid,
case OID_GEN_SUPPORTED_LIST:
count = sizeof(oid_supported_list) / sizeof(uint32_t);
for (i = 0; i < count; i++)
- ((le32 *) outbuf)[i] = cpu_to_le32(oid_supported_list[i]);
+ outbuf32[i] = write_le32(oid_supported_list[i]);
return sizeof(oid_supported_list);
/* mandatory */
case OID_GEN_HARDWARE_STATUS:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_GEN_MEDIA_SUPPORTED:
- *((le32 *) outbuf) = cpu_to_le32(s->medium);
+ outbuf32[0] = write_le32(s->medium);
return sizeof(le32);
/* mandatory */
case OID_GEN_MEDIA_IN_USE:
- *((le32 *) outbuf) = cpu_to_le32(s->medium);
+ outbuf32[0] = write_le32(s->medium);
return sizeof(le32);
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
- *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
+ outbuf32[0] = write_le32(ETH_FRAME_LEN);
return sizeof(le32);
/* mandatory */
case OID_GEN_LINK_SPEED:
- *((le32 *) outbuf) = cpu_to_le32(s->speed);
+ outbuf32[0] = write_le32(s->speed);
return sizeof(le32);
/* mandatory */
case OID_GEN_TRANSMIT_BLOCK_SIZE:
- *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
+ outbuf32[0] = write_le32(ETH_FRAME_LEN);
return sizeof(le32);
/* mandatory */
case OID_GEN_RECEIVE_BLOCK_SIZE:
- *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
+ outbuf32[0] = write_le32(ETH_FRAME_LEN);
return sizeof(le32);
/* mandatory */
case OID_GEN_VENDOR_ID:
- *((le32 *) outbuf) = cpu_to_le32(s->vendorid);
+ outbuf32[0] = write_le32(s->vendorid);
return sizeof(le32);
/* mandatory */
@@ -685,30 +684,30 @@ static int ndis_query(USBNetState *s, uint32_t oid,
return strlen(outbuf) + 1;
case OID_GEN_VENDOR_DRIVER_VERSION:
- *((le32 *) outbuf) = cpu_to_le32(1);
+ outbuf32[0] = write_le32(1);
return sizeof(le32);
/* mandatory */
case OID_GEN_CURRENT_PACKET_FILTER:
- *((le32 *) outbuf) = cpu_to_le32(s->filter);
+ outbuf32[0] = write_le32(s->filter);
return sizeof(le32);
/* mandatory */
case OID_GEN_MAXIMUM_TOTAL_SIZE:
- *((le32 *) outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
+ outbuf32[0] = write_le32(RNDIS_MAX_TOTAL_SIZE);
return sizeof(le32);
/* mandatory */
case OID_GEN_MEDIA_CONNECT_STATUS:
- *((le32 *) outbuf) = cpu_to_le32(s->media_state);
+ outbuf32[0] = write_le32(s->media_state);
return sizeof(le32);
case OID_GEN_PHYSICAL_MEDIUM:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
case OID_GEN_MAC_OPTIONS:
- *((le32 *) outbuf) = cpu_to_le32(
+ outbuf32[0] = write_le32(
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_FULL_DUPLEX);
return sizeof(le32);
@@ -716,27 +715,27 @@ static int ndis_query(USBNetState *s, uint32_t oid,
/* statistics OIDs (table 4-2) */
/* mandatory */
case OID_GEN_XMIT_OK:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_GEN_RCV_OK:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_GEN_XMIT_ERROR:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_GEN_RCV_ERROR:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_GEN_RCV_NO_BUFFER:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* ieee802.3 OIDs (table 4-3) */
@@ -752,12 +751,12 @@ static int ndis_query(USBNetState *s, uint32_t oid,
/* mandatory */
case OID_802_3_MULTICAST_LIST:
- *((le32 *) outbuf) = cpu_to_le32(0xe0000000);
+ outbuf32[0] = write_le32(0xe0000000);
return sizeof(le32);
/* mandatory */
case OID_802_3_MAXIMUM_LIST_SIZE:
- *((le32 *) outbuf) = cpu_to_le32(1);
+ outbuf32[0] = write_le32(1);
return sizeof(le32);
case OID_802_3_MAC_OPTIONS:
@@ -766,17 +765,17 @@ static int ndis_query(USBNetState *s, uint32_t oid,
/* ieee802.3 statistics OIDs (table 4-4) */
/* mandatory */
case OID_802_3_RCV_ERROR_ALIGNMENT:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_802_3_XMIT_ONE_COLLISION:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
/* mandatory */
case OID_802_3_XMIT_MORE_COLLISIONS:
- *((le32 *) outbuf) = cpu_to_le32(0);
+ outbuf32[0] = write_le32(0);
return sizeof(le32);
default:
@@ -789,9 +788,11 @@ static int ndis_query(USBNetState *s, uint32_t oid,
static int ndis_set(USBNetState *s, uint32_t oid,
uint8_t *inbuf, unsigned int inlen)
{
+ le32 *inbuf32 = (void*)inbuf;
+
switch (oid) {
case OID_GEN_CURRENT_PACKET_FILTER:
- s->filter = le32_to_cpup((le32 *) inbuf);
+ s->filter = read_le32(inbuf32[0]);
if (s->filter) {
s->rndis_state = RNDIS_DATA_INITIALIZED;
} else {
@@ -850,20 +851,20 @@ static int rndis_init_response(USBNetState *s, rndis_init_msg_type *buf)
if (!resp)
return USB_RET_STALL;
- resp->MessageType = cpu_to_le32(RNDIS_INITIALIZE_CMPLT);
- resp->MessageLength = cpu_to_le32(sizeof(rndis_init_cmplt_type));
+ resp->MessageType = write_le32(RNDIS_INITIALIZE_CMPLT);
+ resp->MessageLength = write_le32(sizeof(rndis_init_cmplt_type));
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
- resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION);
- resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION);
- resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
- resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3);
- resp->MaxPacketsPerTransfer = cpu_to_le32(1);
- resp->MaxTransferSize = cpu_to_le32(ETH_FRAME_LEN +
+ resp->Status = write_le32(RNDIS_STATUS_SUCCESS);
+ resp->MajorVersion = write_le32(RNDIS_MAJOR_VERSION);
+ resp->MinorVersion = write_le32(RNDIS_MINOR_VERSION);
+ resp->DeviceFlags = write_le32(RNDIS_DF_CONNECTIONLESS);
+ resp->Medium = write_le32(RNDIS_MEDIUM_802_3);
+ resp->MaxPacketsPerTransfer = write_le32(1);
+ resp->MaxTransferSize = write_le32(ETH_FRAME_LEN +
sizeof(struct rndis_packet_msg_type) + 22);
- resp->PacketAlignmentFactor = cpu_to_le32(0);
- resp->AFListOffset = cpu_to_le32(0);
- resp->AFListSize = cpu_to_le32(0);
+ resp->PacketAlignmentFactor = write_le32(0);
+ resp->AFListOffset = write_le32(0);
+ resp->AFListSize = write_le32(0);
return 0;
}
@@ -877,12 +878,12 @@ static int rndis_query_response(USBNetState *s,
int infobuflen;
unsigned int resplen;
- bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
- buflen = le32_to_cpu(buf->InformationBufferLength);
+ bufoffs = read_le32(buf->InformationBufferOffset) + 8;
+ buflen = read_le32(buf->InformationBufferLength);
if (bufoffs + buflen > length)
return USB_RET_STALL;
- infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
+ infobuflen = ndis_query(s, read_le32(buf->OID),
bufoffs + (uint8_t *) buf, buflen, infobuf,
sizeof(infobuf));
resplen = sizeof(rndis_query_cmplt_type) +
@@ -891,22 +892,22 @@ static int rndis_query_response(USBNetState *s,
if (!resp)
return USB_RET_STALL;
- resp->MessageType = cpu_to_le32(RNDIS_QUERY_CMPLT);
+ resp->MessageType = write_le32(RNDIS_QUERY_CMPLT);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->MessageLength = cpu_to_le32(resplen);
+ resp->MessageLength = write_le32(resplen);
if (infobuflen < 0) {
/* OID not supported */
- resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
- resp->InformationBufferLength = cpu_to_le32(0);
- resp->InformationBufferOffset = cpu_to_le32(0);
+ resp->Status = write_le32(RNDIS_STATUS_NOT_SUPPORTED);
+ resp->InformationBufferLength = write_le32(0);
+ resp->InformationBufferOffset = write_le32(0);
return 0;
}
- resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
+ resp->Status = write_le32(RNDIS_STATUS_SUCCESS);
resp->InformationBufferOffset =
- cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0);
- resp->InformationBufferLength = cpu_to_le32(infobuflen);
+ write_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0);
+ resp->InformationBufferLength = write_le32(infobuflen);
memcpy(resp + 1, infobuf, infobuflen);
return 0;
@@ -923,22 +924,22 @@ static int rndis_set_response(USBNetState *s,
if (!resp)
return USB_RET_STALL;
- bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
- buflen = le32_to_cpu(buf->InformationBufferLength);
+ bufoffs = read_le32(buf->InformationBufferOffset) + 8;
+ buflen = read_le32(buf->InformationBufferLength);
if (bufoffs + buflen > length)
return USB_RET_STALL;
- ret = ndis_set(s, le32_to_cpu(buf->OID),
+ ret = ndis_set(s, read_le32(buf->OID),
bufoffs + (uint8_t *) buf, buflen);
- resp->MessageType = cpu_to_le32(RNDIS_SET_CMPLT);
+ resp->MessageType = write_le32(RNDIS_SET_CMPLT);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->MessageLength = cpu_to_le32(sizeof(rndis_set_cmplt_type));
+ resp->MessageLength = write_le32(sizeof(rndis_set_cmplt_type));
if (ret < 0) {
/* OID not supported */
- resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
+ resp->Status = write_le32(RNDIS_STATUS_NOT_SUPPORTED);
return 0;
}
- resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
+ resp->Status = write_le32(RNDIS_STATUS_SUCCESS);
return 0;
}
@@ -951,10 +952,10 @@ static int rndis_reset_response(USBNetState *s, rndis_reset_msg_type *buf)
if (!resp)
return USB_RET_STALL;
- resp->MessageType = cpu_to_le32(RNDIS_RESET_CMPLT);
- resp->MessageLength = cpu_to_le32(sizeof(rndis_reset_cmplt_type));
- resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
- resp->AddressingReset = cpu_to_le32(1); /* reset information */
+ resp->MessageType = write_le32(RNDIS_RESET_CMPLT);
+ resp->MessageLength = write_le32(sizeof(rndis_reset_cmplt_type));
+ resp->Status = write_le32(RNDIS_STATUS_SUCCESS);
+ resp->AddressingReset = write_le32(1); /* reset information */
return 0;
}
@@ -968,10 +969,10 @@ static int rndis_keepalive_response(USBNetState *s,
if (!resp)
return USB_RET_STALL;
- resp->MessageType = cpu_to_le32(RNDIS_KEEPALIVE_CMPLT);
- resp->MessageLength = cpu_to_le32(sizeof(rndis_keepalive_cmplt_type));
+ resp->MessageType = write_le32(RNDIS_KEEPALIVE_CMPLT);
+ resp->MessageLength = write_le32(sizeof(rndis_keepalive_cmplt_type));
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
+ resp->Status = write_le32(RNDIS_STATUS_SUCCESS);
return 0;
}
@@ -979,10 +980,10 @@ static int rndis_keepalive_response(USBNetState *s,
static int rndis_parse(USBNetState *s, uint8_t *data, int length)
{
uint32_t msg_type, msg_length;
- le32 *tmp = (le32 *) data;
+ le32 *data32 = (le32 *) data;
- msg_type = le32_to_cpup(tmp++);
- msg_length = le32_to_cpup(tmp++);
+ msg_type = read_le32(data32[0]);
+ msg_length = read_le32(data32[1]);
switch (msg_type) {
case RNDIS_INITIALIZE_MSG:
@@ -1210,12 +1211,13 @@ static int usb_net_handle_control(USBDevice *dev, int request, int value,
static int usb_net_handle_statusin(USBNetState *s, USBPacket *p)
{
int ret = 8;
+ le32 *data32 = (void*)p->data;
if (p->len < 8)
return USB_RET_STALL;
- ((le32 *) p->data)[0] = cpu_to_le32(1);
- ((le32 *) p->data)[1] = cpu_to_le32(0);
+ data32[0] = write_le32(1);
+ data32[1] = write_le32(0);
if (!s->rndis_resp.tqh_first)
ret = USB_RET_NAK;
@@ -1311,12 +1313,12 @@ static int usb_net_handle_dataout(USBNetState *s, USBPacket *p)
}
return ret;
}
- len = le32_to_cpu(msg->MessageLength);
+ len = read_le32(msg->MessageLength);
if (s->out_ptr < 8 || s->out_ptr < len)
return ret;
- if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
- uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
- uint32_t size = le32_to_cpu(msg->DataLength);
+ if (read_le32(msg->MessageType) == RNDIS_PACKET_MSG) {
+ uint32_t offs = 8 + read_le32(msg->DataOffset);
+ uint32_t size = read_le32(msg->DataLength);
if (offs + size <= len)
qemu_send_packet(s->vc, s->out_buf + offs, size);
}
@@ -1383,10 +1385,10 @@ static void usbnet_receive(void *opaque, const uint8_t *buf, int size)
return;
memset(msg, 0, sizeof(struct rndis_packet_msg_type));
- msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
- msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type));
- msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8);
- msg->DataLength = cpu_to_le32(size);
+ msg->MessageType = write_le32(RNDIS_PACKET_MSG);
+ msg->MessageLength = write_le32(size + sizeof(struct rndis_packet_msg_type));
+ msg->DataOffset = write_le32(sizeof(struct rndis_packet_msg_type) - 8);
+ msg->DataLength = write_le32(size);
/* msg->OOBDataOffset;
* msg->OOBDataLength;
* msg->NumOOBDataElements;
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen).
2008-08-27 13:45 [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu Gerd Hoffmann
@ 2008-08-27 13:45 ` Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 3/4] pci: add default pci subsystem id for all devices Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-08-27 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.h | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/hw/pci.h b/hw/pci.h
index e870987..f518e5e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -6,6 +6,32 @@
/* PCI bus */
+struct pci_config_header {
+ le16 vendor_id;
+ le16 device_id;
+ le16 command;
+ le16 status;
+ uint8_t revision;
+ uint8_t api;
+ uint8_t subclass;
+ uint8_t class;
+ uint8_t cache_line_size; /* Units of 32 bit words */
+ uint8_t latency_timer; /* In units of bus cycles */
+ uint8_t header_type; /* Should be 0 */
+ uint8_t bist; /* Built in self test */
+ le32 base_address_regs[6];
+ le32 reserved1;
+ le16 sub_vendor_id;
+ le16 sub_device_id;
+ le32 rom_addr;
+ le32 reserved3;
+ le32 reserved4;
+ uint8_t interrupt_line;
+ uint8_t interrupt_pin;
+ uint8_t min_gnt;
+ uint8_t max_lat;
+};
+
extern target_phys_addr_t pci_mem_base;
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/4] pci: add default pci subsystem id for all devices.
2008-08-27 13:45 [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
@ 2008-08-27 13:45 ` Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 4/4] pci: use pci_config_header in pci.c Gerd Hoffmann
2008-08-27 14:20 ` [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu M. Warner Losh
3 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-08-27 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This sets a default PCI subsystem ID for all emulated PCI devices. PCI
specs require this, so do it. The defaults are global variables so
they can easily be changed (before device creation) as Xen probably
wants to use the XenSource vendor ID instead of the qemu default.
The defaults are pre-filled by pci_register_device(). Individual
drivers can overwrite it of course when setting up the config space
for the emulated device.
TODO: get an official vendor ID assigned, or borrow one (maybe
Qumranet which already sponsors the virtio IDs ???).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.c | 11 +++++++++++
hw/pci.h | 2 ++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index bc55989..15e8173 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -50,6 +50,8 @@ static void pci_update_mappings(PCIDevice *d);
static void pci_set_irq(void *opaque, int irq_num, int level);
target_phys_addr_t pci_mem_base;
+uint16_t pci_default_sub_vendor_id = 0xfffa; /* FIXME: get one assigned */
+uint16_t pci_default_sub_device_id = 0x0001;
static int pci_irq_index;
static PCIBus *first_bus;
@@ -145,6 +147,14 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
return 0;
}
+static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
+{
+ struct pci_config_header *conf = (void*)pci_dev->config;
+
+ conf->sub_vendor_id = write_le16(pci_default_sub_vendor_id);
+ conf->sub_device_id = write_le16(pci_default_sub_device_id);
+}
+
/* -1 for devfn means auto assign */
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
@@ -171,6 +181,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
+ pci_set_default_subsystem_id(pci_dev);
if (!config_read)
config_read = pci_default_read_config;
diff --git a/hw/pci.h b/hw/pci.h
index f518e5e..28e8fb5 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -33,6 +33,8 @@ struct pci_config_header {
};
extern target_phys_addr_t pci_mem_base;
+extern uint16_t pci_default_sub_vendor_id;
+extern uint16_t pci_default_sub_device_id;
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
uint32_t address, uint32_t data, int len);
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/4] pci: use pci_config_header in pci.c
2008-08-27 13:45 [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 3/4] pci: add default pci subsystem id for all devices Gerd Hoffmann
@ 2008-08-27 13:45 ` Gerd Hoffmann
2008-08-27 14:20 ` [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu M. Warner Losh
3 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-08-27 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This makes use of the new pci_config_header struct in pci.c,
squashing a bunch of casts and hard-coded magic numbers.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.c | 64 +++++++++++++++++++++++++++++++-------------------------------
1 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index 15e8173..bb9fff7 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -199,8 +199,9 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
uint32_t size, int type,
PCIMapIORegionFunc *map_func)
{
+ struct pci_config_header *conf = (void*)pci_dev->config;
PCIIORegion *r;
- uint32_t addr;
+ le32 *addr;
if ((unsigned int)region_num >= PCI_NUM_REGIONS)
return;
@@ -210,11 +211,11 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
r->type = type;
r->map_func = map_func;
if (region_num == PCI_ROM_SLOT) {
- addr = 0x30;
+ addr = &conf->rom_addr;
} else {
- addr = 0x10 + region_num * 4;
+ addr = conf->base_address_regs + region_num;
}
- *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
+ *addr = write_le32(type);
}
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
@@ -224,23 +225,24 @@ static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
static void pci_update_mappings(PCIDevice *d)
{
+ struct pci_config_header *conf = (void*)d->config;
PCIIORegion *r;
int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
+ uint32_t last_addr, new_addr;
+ le32 *config_addr;
- cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
+ cmd = read_le16(conf->command);
for(i = 0; i < PCI_NUM_REGIONS; i++) {
r = &d->io_regions[i];
if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
+ config_addr = &conf->rom_addr;
} else {
- config_ofs = 0x10 + i * 4;
+ config_addr = conf->base_address_regs + i;
}
if (r->size != 0) {
if (r->type & PCI_ADDRESS_SPACE_IO) {
if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
+ new_addr = read_le32(*config_addr);
new_addr = new_addr & ~(r->size - 1);
last_addr = new_addr + r->size - 1;
/* NOTE: we have only 64K ioports on PC */
@@ -253,8 +255,7 @@ static void pci_update_mappings(PCIDevice *d)
}
} else {
if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
+ new_addr = read_le32(*config_addr);
/* the ROM slot has a specific enable bit */
if (i == PCI_ROM_SLOT && !(new_addr & 1))
goto no_mem_map;
@@ -568,13 +569,14 @@ static pci_class_desc pci_class_descriptions[] =
static void pci_info_device(PCIDevice *d)
{
+ struct pci_config_header *conf = (void*)d->config;
int i, class;
PCIIORegion *r;
pci_class_desc *desc;
term_printf(" Bus %2d, device %3d, function %d:\n",
d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
- class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
+ class = conf->class << 8 | conf->subclass;
term_printf(" ");
desc = pci_class_descriptions;
while (desc->desc && class != desc->class)
@@ -585,11 +587,11 @@ static void pci_info_device(PCIDevice *d)
term_printf("Class %04x", class);
}
term_printf(": PCI device %04x:%04x\n",
- le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
- le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
+ read_le16(conf->vendor_id),
+ read_le16(conf->device_id));
- if (d->config[PCI_INTERRUPT_PIN] != 0) {
- term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
+ if (conf->interrupt_line != 0) {
+ term_printf(" IRQ %d.\n", conf->interrupt_line);
}
if (class == 0x0604) {
term_printf(" BUS %d.\n", d->config[0x19]);
@@ -686,25 +688,23 @@ static void pci_bridge_write_config(PCIDevice *d,
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
pci_map_irq_fn map_irq, const char *name)
{
+ struct pci_config_header *conf;
PCIBridge *s;
s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
devfn, NULL, pci_bridge_write_config);
- s->dev.config[0x00] = id >> 16;
- s->dev.config[0x01] = id >> 24;
- s->dev.config[0x02] = id; // device_id
- s->dev.config[0x03] = id >> 8;
- s->dev.config[0x04] = 0x06; // command = bus master, pci mem
- s->dev.config[0x05] = 0x00;
- s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->dev.config[0x07] = 0x00; // status = fast devsel
- s->dev.config[0x08] = 0x00; // revision
- s->dev.config[0x09] = 0x00; // programming i/f
- s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
- s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
- s->dev.config[0x0D] = 0x10; // latency_timer
- s->dev.config[0x0E] = 0x81; // header_type
- s->dev.config[0x1E] = 0xa0; // secondary status
+ conf = (void*)s->dev.config;
+ conf->vendor_id = write_le16(id >> 16);
+ conf->device_id = write_le16(id & 0xffff);
+ conf->command = write_le16(0x0006); // bus master, pci mem
+ conf->status = write_le16(0x00a0); // fast back-to-back, 66MHz, no error, fast devsel
+ conf->revision = 0x00;
+ conf->api = 0x00;
+ conf->subclass = 0x04; // PCI to PCI bridge
+ conf->class = 0x06; // PCI_bridge
+ conf->latency_timer = 0x10;
+ conf->header_type = 0x81;
+ s->dev.config[0x1E] = 0xa0; // secondary status
s->bus = pci_register_secondary_bus(&s->dev, map_irq);
return s->bus;
}
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu.
2008-08-27 13:45 [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu Gerd Hoffmann
` (2 preceding siblings ...)
2008-08-27 13:45 ` [Qemu-devel] [PATCH 4/4] pci: use pci_config_header in pci.c Gerd Hoffmann
@ 2008-08-27 14:20 ` M. Warner Losh
3 siblings, 0 replies; 8+ messages in thread
From: M. Warner Losh @ 2008-08-27 14:20 UTC (permalink / raw)
To: qemu-devel, kraxel
In message: <1219844723-17469-1-git-send-email-kraxel@redhat.com>
Gerd Hoffmann <kraxel@redhat.com> writes:
: +typedef struct { uint16_t le; } le16 __attribute__((__aligned__(2)));
: +typedef struct { uint32_t le; } le32;
: +typedef struct { uint64_t le; } le64;
: +typedef struct { uint16_t be; } be16 __attribute__((__aligned__(2)));
: +typedef struct { uint32_t be; } be32;
: +typedef struct { uint64_t be; } be64;
This is likely still wrong.
There's no packing to ensure that these structures are the right size.
There's no asserts to make sure that these structures really are the
right size.
They are using raw GCCisms, which is both verbose and non-portable.
This may not be a concern in qemu.
#define packed(x) __attribute__((__aligned__(x))) __attribute__((__packed__))
typedef struct { uint16_t le; } le16 packed(2);
typedef struct { uint32_t le; } le32 packed(4);
typedef struct { uint64_t le; } le64 packed(8);
typedef struct { uint16_t be; } be16 packed(2);
typedef struct { uint32_t be; } be32 packed(4);
typedef struct { uint64_t be; } be64 packed(8);
#undef packed
However, something just feels wrong with this approach. I'm sure
there's other subtleties that will bite you with it...
Warner
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen).
2008-08-28 8:36 [Qemu-devel] [PATCH 1/4] add byteordered types " Gerd Hoffmann
@ 2008-08-28 8:36 ` Gerd Hoffmann
0 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-08-28 8:36 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.h | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/hw/pci.h b/hw/pci.h
index e870987..f518e5e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -6,6 +6,32 @@
/* PCI bus */
+struct pci_config_header {
+ le16 vendor_id;
+ le16 device_id;
+ le16 command;
+ le16 status;
+ uint8_t revision;
+ uint8_t api;
+ uint8_t subclass;
+ uint8_t class;
+ uint8_t cache_line_size; /* Units of 32 bit words */
+ uint8_t latency_timer; /* In units of bus cycles */
+ uint8_t header_type; /* Should be 0 */
+ uint8_t bist; /* Built in self test */
+ le32 base_address_regs[6];
+ le32 reserved1;
+ le16 sub_vendor_id;
+ le16 sub_device_id;
+ le32 rom_addr;
+ le32 reserved3;
+ le32 reserved4;
+ uint8_t interrupt_line;
+ uint8_t interrupt_pin;
+ uint8_t min_gnt;
+ uint8_t max_lat;
+};
+
extern target_phys_addr_t pci_mem_base;
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen).
2008-09-10 11:45 [Qemu-devel] [PATCH 1/4] add byteordered types to qemu Gerd Hoffmann
@ 2008-09-10 11:45 ` Gerd Hoffmann
0 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-09-10 11:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.h | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/hw/pci.h b/hw/pci.h
index e870987..f518e5e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -6,6 +6,32 @@
/* PCI bus */
+struct pci_config_header {
+ le16 vendor_id;
+ le16 device_id;
+ le16 command;
+ le16 status;
+ uint8_t revision;
+ uint8_t api;
+ uint8_t subclass;
+ uint8_t class;
+ uint8_t cache_line_size; /* Units of 32 bit words */
+ uint8_t latency_timer; /* In units of bus cycles */
+ uint8_t header_type; /* Should be 0 */
+ uint8_t bist; /* Built in self test */
+ le32 base_address_regs[6];
+ le32 reserved1;
+ le16 sub_vendor_id;
+ le16 sub_device_id;
+ le32 rom_addr;
+ le32 reserved3;
+ le32 reserved4;
+ uint8_t interrupt_line;
+ uint8_t interrupt_pin;
+ uint8_t min_gnt;
+ uint8_t max_lat;
+};
+
extern target_phys_addr_t pci_mem_base;
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen).
2008-10-01 14:12 [Qemu-devel] [PATCH 1/4] add byteordered types to qemu Gerd Hoffmann
@ 2008-10-01 14:12 ` Gerd Hoffmann
0 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2008-10-01 14:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.h | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/hw/pci.h b/hw/pci.h
index e870987..f518e5e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -6,6 +6,32 @@
/* PCI bus */
+struct pci_config_header {
+ le16 vendor_id;
+ le16 device_id;
+ le16 command;
+ le16 status;
+ uint8_t revision;
+ uint8_t api;
+ uint8_t subclass;
+ uint8_t class;
+ uint8_t cache_line_size; /* Units of 32 bit words */
+ uint8_t latency_timer; /* In units of bus cycles */
+ uint8_t header_type; /* Should be 0 */
+ uint8_t bist; /* Built in self test */
+ le32 base_address_regs[6];
+ le32 reserved1;
+ le16 sub_vendor_id;
+ le16 sub_device_id;
+ le32 rom_addr;
+ le32 reserved3;
+ le32 reserved4;
+ uint8_t interrupt_line;
+ uint8_t interrupt_pin;
+ uint8_t min_gnt;
+ uint8_t max_lat;
+};
+
extern target_phys_addr_t pci_mem_base;
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
--
1.5.5.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-10-01 14:13 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-27 13:45 [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 3/4] pci: add default pci subsystem id for all devices Gerd Hoffmann
2008-08-27 13:45 ` [Qemu-devel] [PATCH 4/4] pci: use pci_config_header in pci.c Gerd Hoffmann
2008-08-27 14:20 ` [Qemu-devel] [PATCH 1/4] add byteordered types and accessor functions to qemu M. Warner Losh
-- strict thread matches above, loose matches on Subject: below --
2008-08-28 8:36 [Qemu-devel] [PATCH 1/4] add byteordered types " Gerd Hoffmann
2008-08-28 8:36 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
2008-09-10 11:45 [Qemu-devel] [PATCH 1/4] add byteordered types to qemu Gerd Hoffmann
2008-09-10 11:45 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
2008-10-01 14:12 [Qemu-devel] [PATCH 1/4] add byteordered types to qemu Gerd Hoffmann
2008-10-01 14:12 ` [Qemu-devel] [PATCH 2/4] pci: add config space struct (from qemu-xen) Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).