Add new GET/SET_LOWFLAT() macros and convert appropriate users to them. The new macros make for slightly better code generation.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 6 +++++- src/usb-ehci.c | 40 +++++++++++++++++++--------------------- src/usb-ohci.c | 26 ++++++++++++-------------- src/usb-uhci.c | 43 +++++++++++++++++++++---------------------- 4 files changed, 57 insertions(+), 58 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index b4bd923..294e433 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -250,16 +250,20 @@ static inline u16 get_global_seg(void) { * "Low" memory variables ****************************************************************/
-extern char _datalow_seg; +extern char _datalow_seg, _datalow_base; #define SEG_LOW ((u32)(&_datalow_seg))
#if MODESEGMENT #define GET_LOW(var) GET_FARVAR(SEG_LOW, (var)) #define SET_LOW(var, val) SET_FARVAR(SEG_LOW, (var), (val)) +#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - ((u32)(&_datalow_base)))) #else #define GET_LOW(var) (var) #define SET_LOW(var, val) do { (var) = (val); } while (0) +#define LOWFLAT2LOW(var) (var) #endif +#define GET_LOWFLAT(var) GET_LOW(*LOWFLAT2LOW(&(var))) +#define SET_LOWFLAT(var, val) SET_LOW(*LOWFLAT2LOW(&(var)), (val))
/**************************************************************** diff --git a/src/usb-ehci.c b/src/usb-ehci.c index 6494a3d..0c7cec5 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -520,10 +520,10 @@ ehci_alloc_pipe(struct usbdevice_s *usbdev static void ehci_reset_pipe(struct ehci_pipe *pipe) { - SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM); - SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.qtd_next, EHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.alt_next, EHCI_PTR_TERM); barrier(); - SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE); + SET_LOWFLAT(pipe->qh.token, GET_LOWFLAT(pipe->qh.token) & QTD_TOGGLE); }
static int @@ -536,15 +536,15 @@ ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout) if (!(status & QTD_STS_ACTIVE)) break; if (check_tsc(end)) { - u32 cur = GET_FLATPTR(pipe->qh.current); - u32 tok = GET_FLATPTR(pipe->qh.token); - u32 next = GET_FLATPTR(pipe->qh.qtd_next); + u32 cur = GET_LOWFLAT(pipe->qh.current); + u32 tok = GET_LOWFLAT(pipe->qh.token); + u32 next = GET_LOWFLAT(pipe->qh.qtd_next); warn_timeout(); dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n" , pipe, cur, tok, next, td, status); ehci_reset_pipe(pipe); struct usb_ehci_s *cntl = container_of( - GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb); + GET_LOWFLAT(pipe->pipe.cntl), struct usb_ehci_s, usb); ehci_waittick(cntl); return -1; } @@ -657,9 +657,9 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) struct ehci_qtd *tds = (void*)ALIGN((u32)tdsbuf, EHCI_QTD_ALIGN); memset(tds, 0, sizeof(*tds) * STACKQTDS); barrier(); - SET_FLATPTR(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); + SET_LOWFLAT(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
- u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); + u16 maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); int tdpos = 0; while (datasize) { struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; @@ -698,27 +698,25 @@ ehci_poll_intr(struct usb_pipe *p, void *data) if (! CONFIG_USB_EHCI) return -1; struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - struct ehci_qtd *td = GET_FLATPTR(pipe->next_td); - u32 token = GET_FLATPTR(td->token); + struct ehci_qtd *td = GET_LOWFLAT(pipe->next_td); + u32 token = GET_LOWFLAT(td->token); if (token & QTD_STS_ACTIVE) // No intrs found. return -1; // XXX - check for errors.
// Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int pos = td - GET_FLATPTR(pipe->tds); - void *tddata = GET_FLATPTR(pipe->data) + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) - , maxpacket); + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + int pos = td - GET_LOWFLAT(pipe->tds); + void *tddata = GET_LOWFLAT(pipe->data) + maxpacket * pos; + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(tddata), maxpacket);
// Reenable this td. - struct ehci_qtd *next = (void*)(GET_FLATPTR(td->qtd_next) & ~EHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); - SET_FLATPTR(td->buf[0], (u32)tddata); + struct ehci_qtd *next = (void*)(GET_LOWFLAT(td->qtd_next) & ~EHCI_PTR_BITS); + SET_LOWFLAT(pipe->next_td, next); + SET_LOWFLAT(td->buf[0], (u32)tddata); barrier(); - SET_FLATPTR(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE + SET_LOWFLAT(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE | QTD_PID_IN | ehci_maxerr(3)));
return 0; diff --git a/src/usb-ohci.c b/src/usb-ohci.c index b0d0365..7a8b467 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -504,10 +504,10 @@ ohci_poll_intr(struct usb_pipe *p, void *data) return -1;
struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe); - struct ohci_td *tds = GET_FLATPTR(pipe->tds); - struct ohci_td *head = (void*)(GET_FLATPTR(pipe->ed.hwHeadP) & ~(ED_C|ED_H)); - struct ohci_td *tail = (void*)GET_FLATPTR(pipe->ed.hwTailP); - int count = GET_FLATPTR(pipe->count); + struct ohci_td *tds = GET_LOWFLAT(pipe->tds); + struct ohci_td *head = (void*)(GET_LOWFLAT(pipe->ed.hwHeadP) & ~(ED_C|ED_H)); + struct ohci_td *tail = (void*)GET_LOWFLAT(pipe->ed.hwTailP); + int count = GET_LOWFLAT(pipe->count); int pos = (tail - tds + 1) % count; struct ohci_td *next = &tds[pos]; if (head == next) @@ -516,21 +516,19 @@ ohci_poll_intr(struct usb_pipe *p, void *data) // XXX - check for errors.
// Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - void *pipedata = GET_FLATPTR(pipe->data); + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + void *pipedata = GET_LOWFLAT((pipe->data)); void *intrdata = pipedata + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(intrdata), (void*)FLATPTR_TO_OFFSET(intrdata) - , maxpacket); + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(intrdata), maxpacket);
// Reenable this td. - SET_FLATPTR(tail->hwINFO, TD_DP_IN | TD_T_TOGGLE | TD_CC); + SET_LOWFLAT(tail->hwINFO, TD_DP_IN | TD_T_TOGGLE | TD_CC); intrdata = pipedata + maxpacket * (tail-tds); - SET_FLATPTR(tail->hwCBP, (u32)intrdata); - SET_FLATPTR(tail->hwNextTD, (u32)next); - SET_FLATPTR(tail->hwBE, (u32)intrdata + maxpacket - 1); + SET_LOWFLAT(tail->hwCBP, (u32)intrdata); + SET_LOWFLAT(tail->hwNextTD, (u32)next); + SET_LOWFLAT(tail->hwBE, (u32)intrdata + maxpacket - 1); barrier(); - SET_FLATPTR(pipe->ed.hwTailP, (u32)next); + SET_LOWFLAT(pipe->ed.hwTailP, (u32)next);
return 0; } diff --git a/src/usb-uhci.c b/src/usb-uhci.c index b2677b8..d43114a 100644 --- a/src/usb-uhci.c +++ b/src/usb-uhci.c @@ -388,18 +388,18 @@ wait_pipe(struct uhci_pipe *pipe, int timeout) { u64 end = calc_future_tsc(timeout); for (;;) { - u32 el_link = GET_FLATPTR(pipe->qh.element); + u32 el_link = GET_LOWFLAT(pipe->qh.element); if (el_link & UHCI_PTR_TERM) return 0; if (check_tsc(end)) { warn_timeout(); - u16 iobase = GET_FLATPTR(pipe->iobase); + u16 iobase = GET_LOWFLAT(pipe->iobase); struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS); dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n" - , pipe, (void*)el_link, GET_FLATPTR(td->status) + , pipe, (void*)el_link, GET_LOWFLAT(td->status) , inw(iobase + USBCMD) , inw(iobase + USBSTS)); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM); uhci_waittick(iobase); return -1; } @@ -497,11 +497,11 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); dprintf(7, "uhci_send_bulk qh=%p dir=%d data=%p size=%d\n" , &pipe->qh, dir, data, datasize); - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int lowspeed = GET_FLATPTR(pipe->pipe.speed); - int devaddr = (GET_FLATPTR(pipe->pipe.devaddr) - | (GET_FLATPTR(pipe->pipe.ep) << 7)); - int toggle = GET_FLATPTR(pipe->toggle) ? TD_TOKEN_TOGGLE : 0; + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + int lowspeed = GET_LOWFLAT(pipe->pipe.speed); + int devaddr = (GET_LOWFLAT(pipe->pipe.devaddr) + | (GET_LOWFLAT(pipe->pipe.ep) << 7)); + int toggle = GET_LOWFLAT(pipe->toggle) ? TD_TOKEN_TOGGLE : 0;
// Allocate 4 tds on stack (16byte aligned) u8 tdsbuf[sizeof(struct uhci_td) * STACKTDS + TDALIGN - 1]; @@ -510,7 +510,7 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
// Enable tds barrier(); - SET_FLATPTR(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); + SET_LOWFLAT(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
int tdpos = 0; while (datasize) { @@ -537,12 +537,12 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) data += transfer; datasize -= transfer; } - SET_FLATPTR(pipe->toggle, !!toggle); + SET_LOWFLAT(pipe->toggle, !!toggle); return wait_pipe(pipe, 5000); fail: dprintf(1, "uhci_send_bulk failed\n"); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); - uhci_waittick(GET_FLATPTR(pipe->iobase)); + SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM); + uhci_waittick(GET_LOWFLAT(pipe->iobase)); return -1; }
@@ -554,25 +554,24 @@ uhci_poll_intr(struct usb_pipe *p, void *data) return -1;
struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - struct uhci_td *td = GET_FLATPTR(pipe->next_td); - u32 status = GET_FLATPTR(td->status); - u32 token = GET_FLATPTR(td->token); + struct uhci_td *td = GET_LOWFLAT(pipe->next_td); + u32 status = GET_LOWFLAT(td->status); + u32 token = GET_LOWFLAT(td->token); if (status & TD_CTRL_ACTIVE) // No intrs found. return -1; // XXX - check for errors.
// Copy data. - void *tddata = GET_FLATPTR(td->buffer); - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) + void *tddata = GET_LOWFLAT(td->buffer); + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(tddata) , uhci_expected_length(token));
// Reenable this td. - struct uhci_td *next = (void*)(GET_FLATPTR(td->link) & ~UHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); + struct uhci_td *next = (void*)(GET_LOWFLAT(td->link) & ~UHCI_PTR_BITS); + SET_LOWFLAT(pipe->next_td, next); barrier(); - SET_FLATPTR(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS) + SET_LOWFLAT(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS) | TD_CTRL_ACTIVE));
return 0;